aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2023-12-04 15:32:14 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2023-12-05 01:22:50 +0300
commitc21ed9eedf73010bc81342518177dfdfb0d56bd7 (patch)
tree72f8fde4463080cfe5a38eb0babc051cfe32c51e /library/cpp
parentec1311bf2e8cc231723b8b5e484ca576663a1309 (diff)
downloadydb-c21ed9eedf73010bc81342518177dfdfb0d56bd7.tar.gz
Intermediate changes
Diffstat (limited to 'library/cpp')
-rw-r--r--library/cpp/CMakeLists.darwin-arm64.txt1
-rw-r--r--library/cpp/CMakeLists.darwin-x86_64.txt1
-rw-r--r--library/cpp/CMakeLists.linux-aarch64.txt1
-rw-r--r--library/cpp/CMakeLists.linux-x86_64.txt1
-rw-r--r--library/cpp/CMakeLists.windows-x86_64.txt1
-rw-r--r--library/cpp/actors/CMakeLists.txt24
-rw-r--r--library/cpp/actors/README.md107
-rw-r--r--library/cpp/actors/actor_type/CMakeLists.darwin-arm64.txt33
-rw-r--r--library/cpp/actors/actor_type/CMakeLists.darwin-x86_64.txt33
-rw-r--r--library/cpp/actors/actor_type/CMakeLists.linux-aarch64.txt34
-rw-r--r--library/cpp/actors/actor_type/CMakeLists.linux-x86_64.txt34
-rw-r--r--library/cpp/actors/actor_type/CMakeLists.txt19
-rw-r--r--library/cpp/actors/actor_type/CMakeLists.windows-x86_64.txt33
-rw-r--r--library/cpp/actors/actor_type/common.cpp5
-rw-r--r--library/cpp/actors/actor_type/common.h34
-rw-r--r--library/cpp/actors/actor_type/index_constructor.cpp5
-rw-r--r--library/cpp/actors/actor_type/index_constructor.h12
-rw-r--r--library/cpp/actors/actor_type/indexes.cpp5
-rw-r--r--library/cpp/actors/actor_type/indexes.h31
-rw-r--r--library/cpp/actors/actor_type/ya.make16
-rw-r--r--library/cpp/actors/core/CMakeLists.darwin-arm64.txt101
-rw-r--r--library/cpp/actors/core/CMakeLists.darwin-x86_64.txt101
-rw-r--r--library/cpp/actors/core/CMakeLists.linux-aarch64.txt102
-rw-r--r--library/cpp/actors/core/CMakeLists.linux-x86_64.txt102
-rw-r--r--library/cpp/actors/core/CMakeLists.txt19
-rw-r--r--library/cpp/actors/core/CMakeLists.windows-x86_64.txt101
-rw-r--r--library/cpp/actors/core/README.md51
-rw-r--r--library/cpp/actors/core/actor.cpp250
-rw-r--r--library/cpp/actors/core/actor.h999
-rw-r--r--library/cpp/actors/core/actor_benchmark_helper.h763
-rw-r--r--library/cpp/actors/core/actor_bootstrapped.cpp4
-rw-r--r--library/cpp/actors/core/actor_bootstrapped.h48
-rw-r--r--library/cpp/actors/core/actor_coroutine.cpp182
-rw-r--r--library/cpp/actors/core/actor_coroutine.h230
-rw-r--r--library/cpp/actors/core/actor_coroutine_ut.cpp145
-rw-r--r--library/cpp/actors/core/actor_ut.cpp511
-rw-r--r--library/cpp/actors/core/actor_virtual.cpp6
-rw-r--r--library/cpp/actors/core/actor_virtual.h88
-rw-r--r--library/cpp/actors/core/actorid.cpp34
-rw-r--r--library/cpp/actors/core/actorid.h198
-rw-r--r--library/cpp/actors/core/actorsystem.cpp323
-rw-r--r--library/cpp/actors/core/actorsystem.h311
-rw-r--r--library/cpp/actors/core/actorsystem_ut.cpp45
-rw-r--r--library/cpp/actors/core/ask.cpp76
-rw-r--r--library/cpp/actors/core/ask.h18
-rw-r--r--library/cpp/actors/core/ask_ut.cpp131
-rw-r--r--library/cpp/actors/core/av_bootstrapped.cpp17
-rw-r--r--library/cpp/actors/core/av_bootstrapped.h18
-rw-r--r--library/cpp/actors/core/balancer.cpp311
-rw-r--r--library/cpp/actors/core/balancer.h30
-rw-r--r--library/cpp/actors/core/balancer_ut.cpp225
-rw-r--r--library/cpp/actors/core/benchmark_ut.cpp1111
-rw-r--r--library/cpp/actors/core/buffer.cpp93
-rw-r--r--library/cpp/actors/core/buffer.h62
-rw-r--r--library/cpp/actors/core/callstack.cpp93
-rw-r--r--library/cpp/actors/core/callstack.h58
-rw-r--r--library/cpp/actors/core/config.h260
-rw-r--r--library/cpp/actors/core/cpu_manager.cpp148
-rw-r--r--library/cpp/actors/core/cpu_manager.h55
-rw-r--r--library/cpp/actors/core/cpu_state.h215
-rw-r--r--library/cpp/actors/core/defs.h77
-rw-r--r--library/cpp/actors/core/event.cpp51
-rw-r--r--library/cpp/actors/core/event.h389
-rw-r--r--library/cpp/actors/core/event_load.cpp5
-rw-r--r--library/cpp/actors/core/event_load.h133
-rw-r--r--library/cpp/actors/core/event_local.h74
-rw-r--r--library/cpp/actors/core/event_pb.cpp224
-rw-r--r--library/cpp/actors/core/event_pb.h654
-rw-r--r--library/cpp/actors/core/event_pb_payload_ut.cpp154
-rw-r--r--library/cpp/actors/core/event_pb_ut.cpp71
-rw-r--r--library/cpp/actors/core/events.h224
-rw-r--r--library/cpp/actors/core/events_undelivered.cpp59
-rw-r--r--library/cpp/actors/core/executelater.h86
-rw-r--r--library/cpp/actors/core/executor_pool.h154
-rw-r--r--library/cpp/actors/core/executor_pool_base.cpp271
-rw-r--r--library/cpp/actors/core/executor_pool_base.h62
-rw-r--r--library/cpp/actors/core/executor_pool_basic.cpp749
-rw-r--r--library/cpp/actors/core/executor_pool_basic.h291
-rw-r--r--library/cpp/actors/core/executor_pool_basic_feature_flags.h50
-rw-r--r--library/cpp/actors/core/executor_pool_basic_ut.cpp666
-rw-r--r--library/cpp/actors/core/executor_pool_io.cpp157
-rw-r--r--library/cpp/actors/core/executor_pool_io.h49
-rw-r--r--library/cpp/actors/core/executor_pool_united.cpp1455
-rw-r--r--library/cpp/actors/core/executor_pool_united.h48
-rw-r--r--library/cpp/actors/core/executor_pool_united_ut.cpp341
-rw-r--r--library/cpp/actors/core/executor_pool_united_workers.h105
-rw-r--r--library/cpp/actors/core/executor_thread.cpp714
-rw-r--r--library/cpp/actors/core/executor_thread.h126
-rw-r--r--library/cpp/actors/core/harmonizer.cpp700
-rw-r--r--library/cpp/actors/core/harmonizer.h51
-rw-r--r--library/cpp/actors/core/hfunc.h116
-rw-r--r--library/cpp/actors/core/interconnect.cpp181
-rw-r--r--library/cpp/actors/core/interconnect.h268
-rw-r--r--library/cpp/actors/core/invoke.h145
-rw-r--r--library/cpp/actors/core/io_dispatcher.cpp236
-rw-r--r--library/cpp/actors/core/io_dispatcher.h38
-rw-r--r--library/cpp/actors/core/lease.h56
-rw-r--r--library/cpp/actors/core/log.cpp768
-rw-r--r--library/cpp/actors/core/log.h627
-rw-r--r--library/cpp/actors/core/log_buffer.cpp108
-rw-r--r--library/cpp/actors/core/log_buffer.h40
-rw-r--r--library/cpp/actors/core/log_iface.h117
-rw-r--r--library/cpp/actors/core/log_metrics.h152
-rw-r--r--library/cpp/actors/core/log_settings.cpp232
-rw-r--r--library/cpp/actors/core/log_settings.h175
-rw-r--r--library/cpp/actors/core/log_ut.cpp251
-rw-r--r--library/cpp/actors/core/mailbox.cpp590
-rw-r--r--library/cpp/actors/core/mailbox.h571
-rw-r--r--library/cpp/actors/core/mailbox_queue_revolving.h214
-rw-r--r--library/cpp/actors/core/mailbox_queue_simple.h34
-rw-r--r--library/cpp/actors/core/mon.h267
-rw-r--r--library/cpp/actors/core/mon_stats.h191
-rw-r--r--library/cpp/actors/core/mon_ut.cpp29
-rw-r--r--library/cpp/actors/core/monotonic.cpp1
-rw-r--r--library/cpp/actors/core/monotonic.h12
-rw-r--r--library/cpp/actors/core/monotonic_provider.cpp1
-rw-r--r--library/cpp/actors/core/monotonic_provider.h11
-rw-r--r--library/cpp/actors/core/performance_ut.cpp182
-rw-r--r--library/cpp/actors/core/probes.cpp28
-rw-r--r--library/cpp/actors/core/probes.h221
-rw-r--r--library/cpp/actors/core/process_stats.cpp358
-rw-r--r--library/cpp/actors/core/process_stats.h67
-rw-r--r--library/cpp/actors/core/scheduler_actor.cpp279
-rw-r--r--library/cpp/actors/core/scheduler_actor.h29
-rw-r--r--library/cpp/actors/core/scheduler_actor_ut.cpp100
-rw-r--r--library/cpp/actors/core/scheduler_basic.cpp275
-rw-r--r--library/cpp/actors/core/scheduler_basic.h81
-rw-r--r--library/cpp/actors/core/scheduler_cookie.cpp84
-rw-r--r--library/cpp/actors/core/scheduler_cookie.h78
-rw-r--r--library/cpp/actors/core/scheduler_queue.h123
-rw-r--r--library/cpp/actors/core/servicemap.h168
-rw-r--r--library/cpp/actors/core/thread_context.h30
-rw-r--r--library/cpp/actors/core/tsan.supp3
-rw-r--r--library/cpp/actors/core/ut/CMakeLists.darwin-arm64.txt88
-rw-r--r--library/cpp/actors/core/ut/CMakeLists.darwin-x86_64.txt89
-rw-r--r--library/cpp/actors/core/ut/CMakeLists.linux-aarch64.txt92
-rw-r--r--library/cpp/actors/core/ut/CMakeLists.linux-x86_64.txt94
-rw-r--r--library/cpp/actors/core/ut/CMakeLists.txt19
-rw-r--r--library/cpp/actors/core/ut/CMakeLists.windows-x86_64.txt82
-rw-r--r--library/cpp/actors/core/ut/ya.make43
-rw-r--r--library/cpp/actors/core/ut_fat/CMakeLists.darwin-arm64.txt70
-rw-r--r--library/cpp/actors/core/ut_fat/CMakeLists.darwin-x86_64.txt71
-rw-r--r--library/cpp/actors/core/ut_fat/CMakeLists.linux-aarch64.txt74
-rw-r--r--library/cpp/actors/core/ut_fat/CMakeLists.linux-x86_64.txt76
-rw-r--r--library/cpp/actors/core/ut_fat/CMakeLists.txt19
-rw-r--r--library/cpp/actors/core/ut_fat/CMakeLists.windows-x86_64.txt64
-rw-r--r--library/cpp/actors/core/ut_fat/actor_benchmark.cpp46
-rw-r--r--library/cpp/actors/core/ut_fat/ya.make32
-rw-r--r--library/cpp/actors/core/worker_context.cpp7
-rw-r--r--library/cpp/actors/core/worker_context.h192
-rw-r--r--library/cpp/actors/core/ya.make133
-rw-r--r--library/cpp/actors/cppcoro/CMakeLists.darwin-arm64.txt24
-rw-r--r--library/cpp/actors/cppcoro/CMakeLists.darwin-x86_64.txt24
-rw-r--r--library/cpp/actors/cppcoro/CMakeLists.linux-aarch64.txt25
-rw-r--r--library/cpp/actors/cppcoro/CMakeLists.linux-x86_64.txt25
-rw-r--r--library/cpp/actors/cppcoro/CMakeLists.txt19
-rw-r--r--library/cpp/actors/cppcoro/CMakeLists.windows-x86_64.txt24
-rw-r--r--library/cpp/actors/cppcoro/await_callback.cpp1
-rw-r--r--library/cpp/actors/cppcoro/await_callback.h100
-rw-r--r--library/cpp/actors/cppcoro/corobenchmark/CMakeLists.darwin-arm64.txt30
-rw-r--r--library/cpp/actors/cppcoro/corobenchmark/CMakeLists.darwin-x86_64.txt31
-rw-r--r--library/cpp/actors/cppcoro/corobenchmark/CMakeLists.linux-aarch64.txt34
-rw-r--r--library/cpp/actors/cppcoro/corobenchmark/CMakeLists.linux-x86_64.txt36
-rw-r--r--library/cpp/actors/cppcoro/corobenchmark/CMakeLists.txt19
-rw-r--r--library/cpp/actors/cppcoro/corobenchmark/CMakeLists.windows-x86_64.txt24
-rw-r--r--library/cpp/actors/cppcoro/corobenchmark/main.cpp76
-rw-r--r--library/cpp/actors/cppcoro/corobenchmark/ya.make11
-rw-r--r--library/cpp/actors/cppcoro/task.cpp1
-rw-r--r--library/cpp/actors/cppcoro/task.h228
-rw-r--r--library/cpp/actors/cppcoro/task_actor.cpp183
-rw-r--r--library/cpp/actors/cppcoro/task_actor.h107
-rw-r--r--library/cpp/actors/cppcoro/task_actor_ut.cpp93
-rw-r--r--library/cpp/actors/cppcoro/task_group.cpp1
-rw-r--r--library/cpp/actors/cppcoro/task_group.h302
-rw-r--r--library/cpp/actors/cppcoro/task_result.cpp1
-rw-r--r--library/cpp/actors/cppcoro/task_result.h113
-rw-r--r--library/cpp/actors/cppcoro/task_ut.cpp263
-rw-r--r--library/cpp/actors/cppcoro/ut/CMakeLists.darwin-arm64.txt68
-rw-r--r--library/cpp/actors/cppcoro/ut/CMakeLists.darwin-x86_64.txt69
-rw-r--r--library/cpp/actors/cppcoro/ut/CMakeLists.linux-aarch64.txt72
-rw-r--r--library/cpp/actors/cppcoro/ut/CMakeLists.linux-x86_64.txt74
-rw-r--r--library/cpp/actors/cppcoro/ut/CMakeLists.txt19
-rw-r--r--library/cpp/actors/cppcoro/ut/CMakeLists.windows-x86_64.txt62
-rw-r--r--library/cpp/actors/cppcoro/ut/ya.make12
-rw-r--r--library/cpp/actors/cppcoro/ya.make25
-rw-r--r--library/cpp/actors/dnscachelib/CMakeLists.darwin-arm64.txt21
-rw-r--r--library/cpp/actors/dnscachelib/CMakeLists.darwin-x86_64.txt21
-rw-r--r--library/cpp/actors/dnscachelib/CMakeLists.linux-aarch64.txt22
-rw-r--r--library/cpp/actors/dnscachelib/CMakeLists.linux-x86_64.txt22
-rw-r--r--library/cpp/actors/dnscachelib/CMakeLists.txt19
-rw-r--r--library/cpp/actors/dnscachelib/CMakeLists.windows-x86_64.txt21
-rw-r--r--library/cpp/actors/dnscachelib/dnscache.cpp458
-rw-r--r--library/cpp/actors/dnscachelib/dnscache.h139
-rw-r--r--library/cpp/actors/dnscachelib/probes.cpp3
-rw-r--r--library/cpp/actors/dnscachelib/probes.h35
-rw-r--r--library/cpp/actors/dnscachelib/timekeeper.h70
-rw-r--r--library/cpp/actors/dnscachelib/ya.make23
-rw-r--r--library/cpp/actors/dnsresolver/CMakeLists.darwin-arm64.txt22
-rw-r--r--library/cpp/actors/dnsresolver/CMakeLists.darwin-x86_64.txt22
-rw-r--r--library/cpp/actors/dnsresolver/CMakeLists.linux-aarch64.txt23
-rw-r--r--library/cpp/actors/dnsresolver/CMakeLists.linux-x86_64.txt23
-rw-r--r--library/cpp/actors/dnsresolver/CMakeLists.txt19
-rw-r--r--library/cpp/actors/dnsresolver/CMakeLists.windows-x86_64.txt22
-rw-r--r--library/cpp/actors/dnsresolver/dnsresolver.cpp485
-rw-r--r--library/cpp/actors/dnsresolver/dnsresolver.h128
-rw-r--r--library/cpp/actors/dnsresolver/dnsresolver_caching.cpp694
-rw-r--r--library/cpp/actors/dnsresolver/dnsresolver_caching_ut.cpp648
-rw-r--r--library/cpp/actors/dnsresolver/dnsresolver_ondemand.cpp64
-rw-r--r--library/cpp/actors/dnsresolver/dnsresolver_ondemand_ut.cpp24
-rw-r--r--library/cpp/actors/dnsresolver/dnsresolver_ut.cpp98
-rw-r--r--library/cpp/actors/dnsresolver/ut/CMakeLists.darwin-arm64.txt70
-rw-r--r--library/cpp/actors/dnsresolver/ut/CMakeLists.darwin-x86_64.txt71
-rw-r--r--library/cpp/actors/dnsresolver/ut/CMakeLists.linux-aarch64.txt74
-rw-r--r--library/cpp/actors/dnsresolver/ut/CMakeLists.linux-x86_64.txt76
-rw-r--r--library/cpp/actors/dnsresolver/ut/CMakeLists.txt19
-rw-r--r--library/cpp/actors/dnsresolver/ut/CMakeLists.windows-x86_64.txt64
-rw-r--r--library/cpp/actors/dnsresolver/ut/ya.make18
-rw-r--r--library/cpp/actors/dnsresolver/ya.make18
-rw-r--r--library/cpp/actors/examples/01_ping_pong/CMakeLists.darwin-arm64.txt29
-rw-r--r--library/cpp/actors/examples/01_ping_pong/CMakeLists.darwin-x86_64.txt30
-rw-r--r--library/cpp/actors/examples/01_ping_pong/CMakeLists.linux-aarch64.txt33
-rw-r--r--library/cpp/actors/examples/01_ping_pong/CMakeLists.linux-x86_64.txt34
-rw-r--r--library/cpp/actors/examples/01_ping_pong/CMakeLists.txt19
-rw-r--r--library/cpp/actors/examples/01_ping_pong/CMakeLists.windows-x86_64.txt23
-rw-r--r--library/cpp/actors/examples/01_ping_pong/main.cpp129
-rw-r--r--library/cpp/actors/examples/01_ping_pong/ya.make13
-rw-r--r--library/cpp/actors/examples/02_discovery/CMakeLists.darwin-arm64.txt66
-rw-r--r--library/cpp/actors/examples/02_discovery/CMakeLists.darwin-x86_64.txt67
-rw-r--r--library/cpp/actors/examples/02_discovery/CMakeLists.linux-aarch64.txt70
-rw-r--r--library/cpp/actors/examples/02_discovery/CMakeLists.linux-x86_64.txt71
-rw-r--r--library/cpp/actors/examples/02_discovery/CMakeLists.txt19
-rw-r--r--library/cpp/actors/examples/02_discovery/CMakeLists.windows-x86_64.txt60
-rw-r--r--library/cpp/actors/examples/02_discovery/endpoint.cpp116
-rw-r--r--library/cpp/actors/examples/02_discovery/lookup.cpp132
-rw-r--r--library/cpp/actors/examples/02_discovery/main.cpp136
-rw-r--r--library/cpp/actors/examples/02_discovery/protocol.proto19
-rw-r--r--library/cpp/actors/examples/02_discovery/publish.cpp110
-rw-r--r--library/cpp/actors/examples/02_discovery/replica.cpp181
-rw-r--r--library/cpp/actors/examples/02_discovery/services.h85
-rw-r--r--library/cpp/actors/examples/02_discovery/ya.make25
-rw-r--r--library/cpp/actors/examples/CMakeLists.txt10
-rw-r--r--library/cpp/actors/examples/ya.make4
-rw-r--r--library/cpp/actors/helpers/CMakeLists.darwin-arm64.txt22
-rw-r--r--library/cpp/actors/helpers/CMakeLists.darwin-x86_64.txt22
-rw-r--r--library/cpp/actors/helpers/CMakeLists.linux-aarch64.txt23
-rw-r--r--library/cpp/actors/helpers/CMakeLists.linux-x86_64.txt23
-rw-r--r--library/cpp/actors/helpers/CMakeLists.txt19
-rw-r--r--library/cpp/actors/helpers/CMakeLists.windows-x86_64.txt22
-rw-r--r--library/cpp/actors/helpers/activeactors.cpp2
-rw-r--r--library/cpp/actors/helpers/activeactors.h42
-rw-r--r--library/cpp/actors/helpers/flow_controlled_queue.cpp215
-rw-r--r--library/cpp/actors/helpers/flow_controlled_queue.h19
-rw-r--r--library/cpp/actors/helpers/future_callback.h33
-rw-r--r--library/cpp/actors/helpers/mon_histogram_helper.h86
-rw-r--r--library/cpp/actors/helpers/selfping_actor.cpp208
-rw-r--r--library/cpp/actors/helpers/selfping_actor.h16
-rw-r--r--library/cpp/actors/helpers/selfping_actor_ut.cpp49
-rw-r--r--library/cpp/actors/helpers/ut/CMakeLists.darwin-arm64.txt76
-rw-r--r--library/cpp/actors/helpers/ut/CMakeLists.darwin-x86_64.txt77
-rw-r--r--library/cpp/actors/helpers/ut/CMakeLists.linux-aarch64.txt80
-rw-r--r--library/cpp/actors/helpers/ut/CMakeLists.linux-x86_64.txt82
-rw-r--r--library/cpp/actors/helpers/ut/CMakeLists.txt19
-rw-r--r--library/cpp/actors/helpers/ut/CMakeLists.windows-x86_64.txt70
-rw-r--r--library/cpp/actors/helpers/ut/ya.make31
-rw-r--r--library/cpp/actors/helpers/ya.make23
-rw-r--r--library/cpp/actors/http/CMakeLists.darwin-arm64.txt32
-rw-r--r--library/cpp/actors/http/CMakeLists.darwin-x86_64.txt32
-rw-r--r--library/cpp/actors/http/CMakeLists.linux-aarch64.txt33
-rw-r--r--library/cpp/actors/http/CMakeLists.linux-x86_64.txt33
-rw-r--r--library/cpp/actors/http/CMakeLists.txt19
-rw-r--r--library/cpp/actors/http/CMakeLists.windows-x86_64.txt32
-rw-r--r--library/cpp/actors/http/http.cpp823
-rw-r--r--library/cpp/actors/http/http.h877
-rw-r--r--library/cpp/actors/http/http_cache.cpp608
-rw-r--r--library/cpp/actors/http/http_cache.h27
-rw-r--r--library/cpp/actors/http/http_compress.cpp76
-rw-r--r--library/cpp/actors/http/http_config.h21
-rw-r--r--library/cpp/actors/http/http_proxy.cpp364
-rw-r--r--library/cpp/actors/http/http_proxy.h246
-rw-r--r--library/cpp/actors/http/http_proxy_acceptor.cpp158
-rw-r--r--library/cpp/actors/http/http_proxy_incoming.cpp310
-rw-r--r--library/cpp/actors/http/http_proxy_outgoing.cpp335
-rw-r--r--library/cpp/actors/http/http_proxy_sock64.h147
-rw-r--r--library/cpp/actors/http/http_proxy_sock_impl.h274
-rw-r--r--library/cpp/actors/http/http_proxy_ssl.h133
-rw-r--r--library/cpp/actors/http/http_static.cpp97
-rw-r--r--library/cpp/actors/http/http_static.h9
-rw-r--r--library/cpp/actors/http/http_ut.cpp509
-rw-r--r--library/cpp/actors/http/ut/CMakeLists.darwin-arm64.txt67
-rw-r--r--library/cpp/actors/http/ut/CMakeLists.darwin-x86_64.txt68
-rw-r--r--library/cpp/actors/http/ut/CMakeLists.linux-aarch64.txt71
-rw-r--r--library/cpp/actors/http/ut/CMakeLists.linux-x86_64.txt73
-rw-r--r--library/cpp/actors/http/ut/CMakeLists.txt19
-rw-r--r--library/cpp/actors/http/ut/CMakeLists.windows-x86_64.txt58
-rw-r--r--library/cpp/actors/http/ut/ya.make16
-rw-r--r--library/cpp/actors/http/ya.make36
-rw-r--r--library/cpp/actors/interconnect/CMakeLists.darwin-arm64.txt61
-rw-r--r--library/cpp/actors/interconnect/CMakeLists.darwin-x86_64.txt61
-rw-r--r--library/cpp/actors/interconnect/CMakeLists.linux-aarch64.txt63
-rw-r--r--library/cpp/actors/interconnect/CMakeLists.linux-x86_64.txt63
-rw-r--r--library/cpp/actors/interconnect/CMakeLists.txt19
-rw-r--r--library/cpp/actors/interconnect/CMakeLists.windows-x86_64.txt61
-rw-r--r--library/cpp/actors/interconnect/channel_scheduler.h116
-rw-r--r--library/cpp/actors/interconnect/event_filter.h72
-rw-r--r--library/cpp/actors/interconnect/event_holder_pool.h127
-rw-r--r--library/cpp/actors/interconnect/events_local.h438
-rw-r--r--library/cpp/actors/interconnect/handshake_broker.h156
-rw-r--r--library/cpp/actors/interconnect/interconnect.h189
-rw-r--r--library/cpp/actors/interconnect/interconnect_address.cpp106
-rw-r--r--library/cpp/actors/interconnect/interconnect_address.h47
-rw-r--r--library/cpp/actors/interconnect/interconnect_channel.cpp360
-rw-r--r--library/cpp/actors/interconnect/interconnect_channel.h159
-rw-r--r--library/cpp/actors/interconnect/interconnect_common.h140
-rw-r--r--library/cpp/actors/interconnect/interconnect_counters.cpp703
-rw-r--r--library/cpp/actors/interconnect/interconnect_counters.h57
-rw-r--r--library/cpp/actors/interconnect/interconnect_handshake.cpp1237
-rw-r--r--library/cpp/actors/interconnect/interconnect_handshake.h26
-rw-r--r--library/cpp/actors/interconnect/interconnect_impl.h44
-rw-r--r--library/cpp/actors/interconnect/interconnect_mon.cpp279
-rw-r--r--library/cpp/actors/interconnect/interconnect_mon.h15
-rw-r--r--library/cpp/actors/interconnect/interconnect_nameserver_base.h83
-rw-r--r--library/cpp/actors/interconnect/interconnect_nameserver_dynamic.cpp178
-rw-r--r--library/cpp/actors/interconnect/interconnect_nameserver_table.cpp86
-rw-r--r--library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp47
-rw-r--r--library/cpp/actors/interconnect/interconnect_proxy_wrapper.h12
-rw-r--r--library/cpp/actors/interconnect/interconnect_resolve.cpp208
-rw-r--r--library/cpp/actors/interconnect/interconnect_stream.cpp680
-rw-r--r--library/cpp/actors/interconnect/interconnect_stream.h145
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp1139
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp944
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_proxy.h570
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_server.cpp119
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_server.h58
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_session.cpp1322
-rw-r--r--library/cpp/actors/interconnect/interconnect_tcp_session.h692
-rw-r--r--library/cpp/actors/interconnect/load.cpp405
-rw-r--r--library/cpp/actors/interconnect/load.h24
-rw-r--r--library/cpp/actors/interconnect/logging.h69
-rw-r--r--library/cpp/actors/interconnect/mock/CMakeLists.darwin-arm64.txt18
-rw-r--r--library/cpp/actors/interconnect/mock/CMakeLists.darwin-x86_64.txt18
-rw-r--r--library/cpp/actors/interconnect/mock/CMakeLists.linux-aarch64.txt19
-rw-r--r--library/cpp/actors/interconnect/mock/CMakeLists.linux-x86_64.txt19
-rw-r--r--library/cpp/actors/interconnect/mock/CMakeLists.txt19
-rw-r--r--library/cpp/actors/interconnect/mock/CMakeLists.windows-x86_64.txt18
-rw-r--r--library/cpp/actors/interconnect/mock/ic_mock.cpp385
-rw-r--r--library/cpp/actors/interconnect/mock/ic_mock.h19
-rw-r--r--library/cpp/actors/interconnect/mock/ya.make14
-rw-r--r--library/cpp/actors/interconnect/outgoing_stream.h272
-rw-r--r--library/cpp/actors/interconnect/packet.cpp31
-rw-r--r--library/cpp/actors/interconnect/packet.h304
-rw-r--r--library/cpp/actors/interconnect/poller.h23
-rw-r--r--library/cpp/actors/interconnect/poller_actor.cpp318
-rw-r--r--library/cpp/actors/interconnect/poller_actor.h72
-rw-r--r--library/cpp/actors/interconnect/poller_actor_darwin.h103
-rw-r--r--library/cpp/actors/interconnect/poller_actor_linux.h132
-rw-r--r--library/cpp/actors/interconnect/poller_actor_win.h111
-rw-r--r--library/cpp/actors/interconnect/poller_tcp.cpp35
-rw-r--r--library/cpp/actors/interconnect/poller_tcp.h25
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit.cpp126
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit.h67
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit_epoll.cpp124
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit_epoll.h33
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit_select.cpp86
-rw-r--r--library/cpp/actors/interconnect/poller_tcp_unit_select.h19
-rw-r--r--library/cpp/actors/interconnect/profiler.h142
-rw-r--r--library/cpp/actors/interconnect/slowpoke_actor.h47
-rw-r--r--library/cpp/actors/interconnect/types.cpp564
-rw-r--r--library/cpp/actors/interconnect/types.h72
-rw-r--r--library/cpp/actors/interconnect/ut/CMakeLists.darwin-arm64.txt85
-rw-r--r--library/cpp/actors/interconnect/ut/CMakeLists.darwin-x86_64.txt86
-rw-r--r--library/cpp/actors/interconnect/ut/CMakeLists.linux-aarch64.txt89
-rw-r--r--library/cpp/actors/interconnect/ut/CMakeLists.linux-x86_64.txt91
-rw-r--r--library/cpp/actors/interconnect/ut/CMakeLists.txt19
-rw-r--r--library/cpp/actors/interconnect/ut/CMakeLists.windows-x86_64.txt79
-rw-r--r--library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp117
-rw-r--r--library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp179
-rw-r--r--library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp59
-rw-r--r--library/cpp/actors/interconnect/ut/interconnect_ut.cpp177
-rw-r--r--library/cpp/actors/interconnect/ut/large.cpp85
-rw-r--r--library/cpp/actors/interconnect/ut/lib/CMakeLists.darwin-arm64.txt14
-rw-r--r--library/cpp/actors/interconnect/ut/lib/CMakeLists.darwin-x86_64.txt14
-rw-r--r--library/cpp/actors/interconnect/ut/lib/CMakeLists.linux-aarch64.txt15
-rw-r--r--library/cpp/actors/interconnect/ut/lib/CMakeLists.linux-x86_64.txt15
-rw-r--r--library/cpp/actors/interconnect/ut/lib/CMakeLists.txt19
-rw-r--r--library/cpp/actors/interconnect/ut/lib/CMakeLists.windows-x86_64.txt14
-rw-r--r--library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h87
-rw-r--r--library/cpp/actors/interconnect/ut/lib/interrupter.h249
-rw-r--r--library/cpp/actors/interconnect/ut/lib/node.h149
-rw-r--r--library/cpp/actors/interconnect/ut/lib/test_actors.h83
-rw-r--r--library/cpp/actors/interconnect/ut/lib/test_events.h54
-rw-r--r--library/cpp/actors/interconnect/ut/lib/ya.make10
-rw-r--r--library/cpp/actors/interconnect/ut/outgoing_stream_ut.cpp147
-rw-r--r--library/cpp/actors/interconnect/ut/poller_actor_ut.cpp264
-rw-r--r--library/cpp/actors/interconnect/ut/protos/CMakeLists.darwin-arm64.txt43
-rw-r--r--library/cpp/actors/interconnect/ut/protos/CMakeLists.darwin-x86_64.txt43
-rw-r--r--library/cpp/actors/interconnect/ut/protos/CMakeLists.linux-aarch64.txt44
-rw-r--r--library/cpp/actors/interconnect/ut/protos/CMakeLists.linux-x86_64.txt44
-rw-r--r--library/cpp/actors/interconnect/ut/protos/CMakeLists.txt19
-rw-r--r--library/cpp/actors/interconnect/ut/protos/CMakeLists.windows-x86_64.txt43
-rw-r--r--library/cpp/actors/interconnect/ut/protos/interconnect_test.proto28
-rw-r--r--library/cpp/actors/interconnect/ut/protos/ya.make9
-rw-r--r--library/cpp/actors/interconnect/ut/sticking_ut.cpp108
-rw-r--r--library/cpp/actors/interconnect/ut/ya.make33
-rw-r--r--library/cpp/actors/interconnect/ut_fat/CMakeLists.darwin-arm64.txt69
-rw-r--r--library/cpp/actors/interconnect/ut_fat/CMakeLists.darwin-x86_64.txt70
-rw-r--r--library/cpp/actors/interconnect/ut_fat/CMakeLists.linux-aarch64.txt73
-rw-r--r--library/cpp/actors/interconnect/ut_fat/CMakeLists.linux-x86_64.txt75
-rw-r--r--library/cpp/actors/interconnect/ut_fat/CMakeLists.txt19
-rw-r--r--library/cpp/actors/interconnect/ut_fat/CMakeLists.windows-x86_64.txt63
-rw-r--r--library/cpp/actors/interconnect/ut_fat/main.cpp133
-rw-r--r--library/cpp/actors/interconnect/ut_fat/ya.make21
-rw-r--r--library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.darwin-arm64.txt75
-rw-r--r--library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.darwin-x86_64.txt76
-rw-r--r--library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.linux-aarch64.txt79
-rw-r--r--library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.linux-x86_64.txt81
-rw-r--r--library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.txt19
-rw-r--r--library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.windows-x86_64.txt69
-rw-r--r--library/cpp/actors/interconnect/ut_huge_cluster/huge_cluster.cpp167
-rw-r--r--library/cpp/actors/interconnect/ut_huge_cluster/ya.make34
-rw-r--r--library/cpp/actors/interconnect/watchdog_timer.h69
-rw-r--r--library/cpp/actors/interconnect/ya.make97
-rw-r--r--library/cpp/actors/log_backend/CMakeLists.darwin-arm64.txt19
-rw-r--r--library/cpp/actors/log_backend/CMakeLists.darwin-x86_64.txt19
-rw-r--r--library/cpp/actors/log_backend/CMakeLists.linux-aarch64.txt20
-rw-r--r--library/cpp/actors/log_backend/CMakeLists.linux-x86_64.txt20
-rw-r--r--library/cpp/actors/log_backend/CMakeLists.txt19
-rw-r--r--library/cpp/actors/log_backend/CMakeLists.windows-x86_64.txt19
-rw-r--r--library/cpp/actors/log_backend/actor_log_backend.cpp42
-rw-r--r--library/cpp/actors/log_backend/actor_log_backend.h20
-rw-r--r--library/cpp/actors/log_backend/ya.make12
-rw-r--r--library/cpp/actors/memory_log/CMakeLists.darwin-arm64.txt21
-rw-r--r--library/cpp/actors/memory_log/CMakeLists.darwin-x86_64.txt21
-rw-r--r--library/cpp/actors/memory_log/CMakeLists.linux-aarch64.txt22
-rw-r--r--library/cpp/actors/memory_log/CMakeLists.linux-x86_64.txt22
-rw-r--r--library/cpp/actors/memory_log/CMakeLists.txt19
-rw-r--r--library/cpp/actors/memory_log/CMakeLists.windows-x86_64.txt21
-rw-r--r--library/cpp/actors/memory_log/memlog.cpp367
-rw-r--r--library/cpp/actors/memory_log/memlog.h211
-rw-r--r--library/cpp/actors/memory_log/mmap.cpp63
-rw-r--r--library/cpp/actors/memory_log/ya.make15
-rw-r--r--library/cpp/actors/prof/CMakeLists.darwin-arm64.txt22
-rw-r--r--library/cpp/actors/prof/CMakeLists.darwin-x86_64.txt22
-rw-r--r--library/cpp/actors/prof/CMakeLists.linux-aarch64.txt23
-rw-r--r--library/cpp/actors/prof/CMakeLists.linux-x86_64.txt23
-rw-r--r--library/cpp/actors/prof/CMakeLists.txt19
-rw-r--r--library/cpp/actors/prof/CMakeLists.windows-x86_64.txt22
-rw-r--r--library/cpp/actors/prof/tag.cpp132
-rw-r--r--library/cpp/actors/prof/tag.h84
-rw-r--r--library/cpp/actors/prof/tcmalloc.cpp32
-rw-r--r--library/cpp/actors/prof/tcmalloc.h9
-rw-r--r--library/cpp/actors/prof/ut/CMakeLists.darwin-arm64.txt66
-rw-r--r--library/cpp/actors/prof/ut/CMakeLists.darwin-x86_64.txt67
-rw-r--r--library/cpp/actors/prof/ut/CMakeLists.linux-aarch64.txt70
-rw-r--r--library/cpp/actors/prof/ut/CMakeLists.linux-x86_64.txt72
-rw-r--r--library/cpp/actors/prof/ut/CMakeLists.txt19
-rw-r--r--library/cpp/actors/prof/ut/CMakeLists.windows-x86_64.txt60
-rw-r--r--library/cpp/actors/prof/ut/tag_ut.cpp68
-rw-r--r--library/cpp/actors/prof/ut/ya.make7
-rw-r--r--library/cpp/actors/prof/ya.make28
-rw-r--r--library/cpp/actors/protos/CMakeLists.darwin-arm64.txt82
-rw-r--r--library/cpp/actors/protos/CMakeLists.darwin-x86_64.txt82
-rw-r--r--library/cpp/actors/protos/CMakeLists.linux-aarch64.txt83
-rw-r--r--library/cpp/actors/protos/CMakeLists.linux-x86_64.txt83
-rw-r--r--library/cpp/actors/protos/CMakeLists.txt19
-rw-r--r--library/cpp/actors/protos/CMakeLists.windows-x86_64.txt82
-rw-r--r--library/cpp/actors/protos/actors.proto41
-rw-r--r--library/cpp/actors/protos/interconnect.proto133
-rw-r--r--library/cpp/actors/protos/services_common.proto22
-rw-r--r--library/cpp/actors/protos/unittests.proto20
-rw-r--r--library/cpp/actors/protos/ya.make12
-rw-r--r--library/cpp/actors/testlib/CMakeLists.darwin-arm64.txt23
-rw-r--r--library/cpp/actors/testlib/CMakeLists.darwin-x86_64.txt23
-rw-r--r--library/cpp/actors/testlib/CMakeLists.linux-aarch64.txt24
-rw-r--r--library/cpp/actors/testlib/CMakeLists.linux-x86_64.txt24
-rw-r--r--library/cpp/actors/testlib/CMakeLists.txt19
-rw-r--r--library/cpp/actors/testlib/CMakeLists.windows-x86_64.txt23
-rw-r--r--library/cpp/actors/testlib/decorator_ut.cpp327
-rw-r--r--library/cpp/actors/testlib/test_runtime.cpp1968
-rw-r--r--library/cpp/actors/testlib/test_runtime.h814
-rw-r--r--library/cpp/actors/testlib/ut/CMakeLists.darwin-arm64.txt67
-rw-r--r--library/cpp/actors/testlib/ut/CMakeLists.darwin-x86_64.txt68
-rw-r--r--library/cpp/actors/testlib/ut/CMakeLists.linux-aarch64.txt71
-rw-r--r--library/cpp/actors/testlib/ut/CMakeLists.linux-x86_64.txt73
-rw-r--r--library/cpp/actors/testlib/ut/CMakeLists.txt19
-rw-r--r--library/cpp/actors/testlib/ut/CMakeLists.windows-x86_64.txt61
-rw-r--r--library/cpp/actors/testlib/ut/ya.make15
-rw-r--r--library/cpp/actors/testlib/ya.make23
-rw-r--r--library/cpp/actors/util/CMakeLists.darwin-arm64.txt28
-rw-r--r--library/cpp/actors/util/CMakeLists.darwin-x86_64.txt28
-rw-r--r--library/cpp/actors/util/CMakeLists.linux-aarch64.txt29
-rw-r--r--library/cpp/actors/util/CMakeLists.linux-x86_64.txt29
-rw-r--r--library/cpp/actors/util/CMakeLists.txt19
-rw-r--r--library/cpp/actors/util/CMakeLists.windows-x86_64.txt28
-rw-r--r--library/cpp/actors/util/README.md99
-rw-r--r--library/cpp/actors/util/affinity.cpp93
-rw-r--r--library/cpp/actors/util/affinity.h49
-rw-r--r--library/cpp/actors/util/cpu_load_log.h227
-rw-r--r--library/cpp/actors/util/cpu_load_log_ut.cpp275
-rw-r--r--library/cpp/actors/util/cpumask.h133
-rw-r--r--library/cpp/actors/util/datetime.h82
-rw-r--r--library/cpp/actors/util/defs.h16
-rw-r--r--library/cpp/actors/util/funnel_queue.h240
-rw-r--r--library/cpp/actors/util/futex.h13
-rw-r--r--library/cpp/actors/util/intrinsics.h97
-rw-r--r--library/cpp/actors/util/local_process_key.h157
-rw-r--r--library/cpp/actors/util/memory_track.cpp38
-rw-r--r--library/cpp/actors/util/memory_track.h293
-rw-r--r--library/cpp/actors/util/memory_tracker.cpp103
-rw-r--r--library/cpp/actors/util/memory_tracker.h53
-rw-r--r--library/cpp/actors/util/memory_tracker_ut.cpp263
-rw-r--r--library/cpp/actors/util/named_tuple.h30
-rw-r--r--library/cpp/actors/util/queue_chunk.h29
-rw-r--r--library/cpp/actors/util/queue_oneone_inplace.h118
-rw-r--r--library/cpp/actors/util/rc_buf.cpp6
-rw-r--r--library/cpp/actors/util/rc_buf.h1120
-rw-r--r--library/cpp/actors/util/rc_buf_backend.h230
-rw-r--r--library/cpp/actors/util/rc_buf_ut.cpp207
-rw-r--r--library/cpp/actors/util/recentwnd.h67
-rw-r--r--library/cpp/actors/util/rope.cpp13
-rw-r--r--library/cpp/actors/util/rope.h1148
-rw-r--r--library/cpp/actors/util/rope_cont_embedded_list.h391
-rw-r--r--library/cpp/actors/util/rope_ut.cpp418
-rw-r--r--library/cpp/actors/util/shared_data.cpp49
-rw-r--r--library/cpp/actors/util/shared_data.h227
-rw-r--r--library/cpp/actors/util/shared_data_backtracing_owner.h88
-rw-r--r--library/cpp/actors/util/shared_data_native_rope_backend_ut.cpp231
-rw-r--r--library/cpp/actors/util/shared_data_rope_backend.h41
-rw-r--r--library/cpp/actors/util/shared_data_rope_backend_ut.cpp231
-rw-r--r--library/cpp/actors/util/shared_data_ut.cpp205
-rw-r--r--library/cpp/actors/util/should_continue.cpp23
-rw-r--r--library/cpp/actors/util/should_continue.h22
-rw-r--r--library/cpp/actors/util/thread.h26
-rw-r--r--library/cpp/actors/util/thread_load_log.h363
-rw-r--r--library/cpp/actors/util/thread_load_log_ut.cpp966
-rw-r--r--library/cpp/actors/util/threadparkpad.cpp152
-rw-r--r--library/cpp/actors/util/threadparkpad.h21
-rw-r--r--library/cpp/actors/util/ticket_lock.h48
-rw-r--r--library/cpp/actors/util/timerfd.h65
-rw-r--r--library/cpp/actors/util/unordered_cache.h201
-rw-r--r--library/cpp/actors/util/unordered_cache_ut.cpp138
-rw-r--r--library/cpp/actors/util/ut/CMakeLists.darwin-arm64.txt74
-rw-r--r--library/cpp/actors/util/ut/CMakeLists.darwin-x86_64.txt75
-rw-r--r--library/cpp/actors/util/ut/CMakeLists.linux-aarch64.txt78
-rw-r--r--library/cpp/actors/util/ut/CMakeLists.linux-x86_64.txt80
-rw-r--r--library/cpp/actors/util/ut/CMakeLists.txt19
-rw-r--r--library/cpp/actors/util/ut/CMakeLists.windows-x86_64.txt68
-rw-r--r--library/cpp/actors/util/ut/ya.make20
-rw-r--r--library/cpp/actors/util/ut_helpers.h12
-rw-r--r--library/cpp/actors/util/ya.make50
-rw-r--r--library/cpp/actors/wilson/CMakeLists.darwin-arm64.txt25
-rw-r--r--library/cpp/actors/wilson/CMakeLists.darwin-x86_64.txt25
-rw-r--r--library/cpp/actors/wilson/CMakeLists.linux-aarch64.txt26
-rw-r--r--library/cpp/actors/wilson/CMakeLists.linux-x86_64.txt26
-rw-r--r--library/cpp/actors/wilson/CMakeLists.txt19
-rw-r--r--library/cpp/actors/wilson/CMakeLists.windows-x86_64.txt25
-rw-r--r--library/cpp/actors/wilson/protos/CMakeLists.darwin-arm64.txt15
-rw-r--r--library/cpp/actors/wilson/protos/CMakeLists.darwin-x86_64.txt15
-rw-r--r--library/cpp/actors/wilson/protos/CMakeLists.linux-aarch64.txt16
-rw-r--r--library/cpp/actors/wilson/protos/CMakeLists.linux-x86_64.txt16
-rw-r--r--library/cpp/actors/wilson/protos/CMakeLists.txt19
-rw-r--r--library/cpp/actors/wilson/protos/CMakeLists.windows-x86_64.txt15
-rw-r--r--library/cpp/actors/wilson/protos/ya.make12
-rw-r--r--library/cpp/actors/wilson/wilson_event.cpp4
-rw-r--r--library/cpp/actors/wilson/wilson_event.h21
-rw-r--r--library/cpp/actors/wilson/wilson_profile_span.cpp178
-rw-r--r--library/cpp/actors/wilson/wilson_profile_span.h75
-rw-r--r--library/cpp/actors/wilson/wilson_span.cpp62
-rw-r--r--library/cpp/actors/wilson/wilson_span.h244
-rw-r--r--library/cpp/actors/wilson/wilson_trace.cpp4
-rw-r--r--library/cpp/actors/wilson/wilson_trace.h234
-rw-r--r--library/cpp/actors/wilson/wilson_uploader.cpp193
-rw-r--r--library/cpp/actors/wilson/wilson_uploader.h24
-rw-r--r--library/cpp/actors/wilson/ya.make21
-rw-r--r--library/cpp/actors/ya.make16
-rw-r--r--library/cpp/deprecated/autoarray/README.md3
-rw-r--r--library/cpp/deprecated/autoarray/autoarray.cpp1
-rw-r--r--library/cpp/deprecated/autoarray/autoarray.h264
-rw-r--r--library/cpp/deprecated/autoarray/ya.make7
-rw-r--r--library/cpp/deprecated/fgood/README.md15
-rw-r--r--library/cpp/deprecated/fgood/ffb.cpp407
-rw-r--r--library/cpp/deprecated/fgood/ffb.h264
-rw-r--r--library/cpp/deprecated/fgood/fgood.cpp70
-rw-r--r--library/cpp/deprecated/fgood/fgood.h328
-rw-r--r--library/cpp/deprecated/fgood/fput.h79
-rw-r--r--library/cpp/deprecated/fgood/ya.make8
-rw-r--r--library/cpp/deprecated/mapped_file/mapped_file.cpp64
-rw-r--r--library/cpp/deprecated/mapped_file/ya.make7
-rw-r--r--library/cpp/eventlog/common.h10
-rw-r--r--library/cpp/eventlog/evdecoder.cpp112
-rw-r--r--library/cpp/eventlog/evdecoder.h16
-rw-r--r--library/cpp/eventlog/event_field_output.cpp68
-rw-r--r--library/cpp/eventlog/event_field_output.h29
-rw-r--r--library/cpp/eventlog/event_field_printer.cpp27
-rw-r--r--library/cpp/eventlog/event_field_printer.h38
-rw-r--r--library/cpp/eventlog/eventlog.cpp554
-rw-r--r--library/cpp/eventlog/eventlog.h623
-rw-r--r--library/cpp/eventlog/eventlog_int.cpp12
-rw-r--r--library/cpp/eventlog/eventlog_int.h72
-rw-r--r--library/cpp/eventlog/events_extension.h161
-rw-r--r--library/cpp/eventlog/iterator.cpp88
-rw-r--r--library/cpp/eventlog/iterator.h51
-rw-r--r--library/cpp/eventlog/logparser.cpp814
-rw-r--r--library/cpp/eventlog/logparser.h343
-rw-r--r--library/cpp/eventlog/proto/events_extension.proto22
-rw-r--r--library/cpp/eventlog/proto/internal.proto9
-rw-r--r--library/cpp/eventlog/proto/ya.make12
-rw-r--r--library/cpp/eventlog/threaded_eventlog.cpp1
-rw-r--r--library/cpp/eventlog/threaded_eventlog.h154
-rw-r--r--library/cpp/eventlog/ya.make29
-rw-r--r--library/cpp/fieldcalc/field_calc.cpp1136
-rw-r--r--library/cpp/fieldcalc/field_calc.h136
-rw-r--r--library/cpp/fieldcalc/field_calc_int.h593
-rw-r--r--library/cpp/fieldcalc/lossy_types.h52
-rw-r--r--library/cpp/fieldcalc/ya.make13
-rw-r--r--library/cpp/malloc/galloc/malloc-info.cpp9
-rw-r--r--library/cpp/malloc/galloc/ya.make15
-rw-r--r--library/cpp/on_disk/multi_blob/multiblob.cpp67
-rw-r--r--library/cpp/on_disk/multi_blob/multiblob.h77
-rw-r--r--library/cpp/on_disk/multi_blob/multiblob_builder.cpp146
-rw-r--r--library/cpp/on_disk/multi_blob/multiblob_builder.h64
-rw-r--r--library/cpp/on_disk/multi_blob/ya.make13
-rw-r--r--library/cpp/on_disk/st_hash/fake.cpp4
-rw-r--r--library/cpp/on_disk/st_hash/save_stl.h84
-rw-r--r--library/cpp/on_disk/st_hash/static_hash.h420
-rw-r--r--library/cpp/on_disk/st_hash/static_hash_map.h59
-rw-r--r--library/cpp/on_disk/st_hash/sthash_iterators.h334
-rw-r--r--library/cpp/on_disk/st_hash/ya.make15
-rw-r--r--library/cpp/remmap/remmap.cpp138
-rw-r--r--library/cpp/remmap/remmap.h64
-rw-r--r--library/cpp/remmap/ya.make7
-rw-r--r--library/cpp/sqlite3/sqlite.cpp288
-rw-r--r--library/cpp/sqlite3/sqlite.h136
-rw-r--r--library/cpp/sqlite3/ya.make13
-rw-r--r--library/cpp/streams/growing_file_input/growing_file_input.cpp40
-rw-r--r--library/cpp/streams/growing_file_input/growing_file_input.h23
-rw-r--r--library/cpp/streams/growing_file_input/ya.make11
-rw-r--r--library/cpp/string_utils/subst_buf/substbuf.cpp1
-rw-r--r--library/cpp/string_utils/subst_buf/substbuf.h63
-rw-r--r--library/cpp/string_utils/subst_buf/ya.make7
-rw-r--r--library/cpp/ucompress/README.md1
-rw-r--r--library/cpp/ucompress/common.h8
-rw-r--r--library/cpp/ucompress/reader.cpp58
-rw-r--r--library/cpp/ucompress/reader.h25
-rw-r--r--library/cpp/ucompress/writer.cpp95
-rw-r--r--library/cpp/ucompress/writer.h31
-rw-r--r--library/cpp/ucompress/ya.make18
-rw-r--r--library/cpp/zipatch/reader.cpp173
-rw-r--r--library/cpp/zipatch/reader.h48
-rw-r--r--library/cpp/zipatch/writer.cpp232
-rw-r--r--library/cpp/zipatch/writer.h51
-rw-r--r--library/cpp/zipatch/ya.make16
651 files changed, 0 insertions, 84412 deletions
diff --git a/library/cpp/CMakeLists.darwin-arm64.txt b/library/cpp/CMakeLists.darwin-arm64.txt
index 58a86cdbb5..918b7e4c77 100644
--- a/library/cpp/CMakeLists.darwin-arm64.txt
+++ b/library/cpp/CMakeLists.darwin-arm64.txt
@@ -7,7 +7,6 @@
add_subdirectory(accurate_accumulate)
-add_subdirectory(actors)
add_subdirectory(archive)
add_subdirectory(balloc)
add_subdirectory(binsaver)
diff --git a/library/cpp/CMakeLists.darwin-x86_64.txt b/library/cpp/CMakeLists.darwin-x86_64.txt
index 5692463e65..4656f580ad 100644
--- a/library/cpp/CMakeLists.darwin-x86_64.txt
+++ b/library/cpp/CMakeLists.darwin-x86_64.txt
@@ -7,7 +7,6 @@
add_subdirectory(accurate_accumulate)
-add_subdirectory(actors)
add_subdirectory(archive)
add_subdirectory(balloc)
add_subdirectory(binsaver)
diff --git a/library/cpp/CMakeLists.linux-aarch64.txt b/library/cpp/CMakeLists.linux-aarch64.txt
index 58a86cdbb5..918b7e4c77 100644
--- a/library/cpp/CMakeLists.linux-aarch64.txt
+++ b/library/cpp/CMakeLists.linux-aarch64.txt
@@ -7,7 +7,6 @@
add_subdirectory(accurate_accumulate)
-add_subdirectory(actors)
add_subdirectory(archive)
add_subdirectory(balloc)
add_subdirectory(binsaver)
diff --git a/library/cpp/CMakeLists.linux-x86_64.txt b/library/cpp/CMakeLists.linux-x86_64.txt
index 5692463e65..4656f580ad 100644
--- a/library/cpp/CMakeLists.linux-x86_64.txt
+++ b/library/cpp/CMakeLists.linux-x86_64.txt
@@ -7,7 +7,6 @@
add_subdirectory(accurate_accumulate)
-add_subdirectory(actors)
add_subdirectory(archive)
add_subdirectory(balloc)
add_subdirectory(binsaver)
diff --git a/library/cpp/CMakeLists.windows-x86_64.txt b/library/cpp/CMakeLists.windows-x86_64.txt
index d8d81b3185..7867eb1061 100644
--- a/library/cpp/CMakeLists.windows-x86_64.txt
+++ b/library/cpp/CMakeLists.windows-x86_64.txt
@@ -7,7 +7,6 @@
add_subdirectory(accurate_accumulate)
-add_subdirectory(actors)
add_subdirectory(archive)
add_subdirectory(balloc)
add_subdirectory(binsaver)
diff --git a/library/cpp/actors/CMakeLists.txt b/library/cpp/actors/CMakeLists.txt
deleted file mode 100644
index becd73cd24..0000000000
--- a/library/cpp/actors/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(actor_type)
-add_subdirectory(core)
-add_subdirectory(cppcoro)
-add_subdirectory(dnscachelib)
-add_subdirectory(dnsresolver)
-add_subdirectory(examples)
-add_subdirectory(helpers)
-add_subdirectory(http)
-add_subdirectory(interconnect)
-add_subdirectory(log_backend)
-add_subdirectory(memory_log)
-add_subdirectory(prof)
-add_subdirectory(protos)
-add_subdirectory(testlib)
-add_subdirectory(util)
-add_subdirectory(wilson)
diff --git a/library/cpp/actors/README.md b/library/cpp/actors/README.md
deleted file mode 100644
index 22502c391a..0000000000
--- a/library/cpp/actors/README.md
+++ /dev/null
@@ -1,107 +0,0 @@
-## Actor library
-
-### Часть первая, вводная.
-Иногда приходится разрабатывать асинхронные, существенно параллельные, местами распределённые программы. Иногда еще и внутренняя логика нетривиальна, разнородна, пишется разными командами не один год. Всё как мы любим. Человечеством придумано не так много способов внутренней организации структуры и кода таких программ. Большинство из них плохие (и именно из-за плохих подходов разработка асинхронных, многопоточных программ приобрела дурную славу). Некоторые получше. А серебряной пули как обычно нет.
-
-Когда мы начинали разработку Yandex Database (тогда еще KiKiMR), сразу было понятно что простыми наколеночными поделиями обойтись (и сделать при этом хорошо, так что бы не было стыдно) не получится. В качестве базиса мы выбрали мессадж-пассинг и модель акторов. И не пожалели. Постепенно этот подход распространился на смежные проекты.
-
-### Базовые концепции.
-Если отбросить шелуху – представляем сервис (программу в случае запуска изолированного бинарника) как ансамбль независимых агентов, взаимодействующих через отправку асинхронных сообщений внутри общего окружения. Тут все слова важны:
-
-Независимых – не разделяют состояние и поток выполнения.
-Передача сообщений – формализуем протоколы, а не интерфейсы.
-
-Асинхронная – не блокируемся на отправке сообщений.
-Общее окружение – все агенты разделяют общий пул ресурсов и каждый из них, зная адрес, может послать сообщение каждому.
-
-В более хайповых терминах – очень похоже на колокейтед микросервисы, только уровнем ниже. И да, мы заведомо не хотели прятать асинхронщину и параллелизм от разработчика, показывая прям самое мясо.
-
-### IActor.
-https://a.yandex-team.ru/arcadia/library/cpp/actors/core/actor.h?rev=r11291267#L310
-Базовый класс всех агентов, напрямую обычно не используется. Инстанцируется либо TActor, либо TActorBootstrapped. Фактически весь полезный код программы размещается в акторах.
-(важное замечание – в коде увидите ручки с TActorContext и без него, схожие по названию и назначению. На данный момент вариант с TActorContext является устаревшим, новый код стоит писать без его использования).
-Важные методы:
-
-PassAway – единственный корректный способ зарегистрированному актору умереть. Может вызываться только находясь внутри обработчика сообщения.
-Send – отправка сообщения, зная адрес получателя. В акторе доступен хелпер, принимающий непосредственно сообщение. Базовый вызов, принимающий полный event handle – доступен в контексте.
-
-Become – установить функцию-обработчик сообщений, которая будет использована при получении следующего сообщения.
-
-Register – зарегистрировать новый актор в акторсистеме, с выделением нового мейлбокса. Важно – с момента вызова владение актором передается акторсистеме, т.е. уже к моменту выхода актор может начать выполняться на другом потоке, нельзя к нему ни обращаться прямыми вызовами, ни даже предполагать что он еще жив.
-
-Schedule – зарегистрировать сообщение, которое будет отправлено не менее чем через запрошенную задержку. В акторе доступен хелпер, декорирующий сообщение хендлом отправки самому себе, в контексте можно передать полный хендл.
-
-SelfId – узнать собственный адрес. Возвращаемый объект TActorIdentity можно передавать если требуется делегировать отправку сообщений от имени актора (например если пишете полезный код пользуясь пассивными объектами).
-Посылка сообщений дешёвая, не нужно на ней чрезмерно экономить (но не бесплатная – поэтому посылать сообщения только ради посылки сообщений то же не стоит).
-
-Инстанцирование акторов так же дёшево, актор на запрос или фазу запроса – вполне нормальная практика. Мультиплексировать обработку разных запросов в одном акторе – так же вполне нормально. В нашем коде много примеров и первого, и второго. Пользуйтесь здравым смыслов и собственным вкусом.
-Т.к. на время обработки сообщения актор занимает тред из пула акторсистемы – уходить в длинные вычисления лучше на отдельном отселённом акторе (и либо отселять в отдельный пол акторсистемы, либо контролировать параллельность брокером ресурсов), блокирующие вызовы делать почти всегда ошибка. Стремление написать мютекс - ересь и от лукавого.
-Идентифицируются акторы своим TActorID-ом, который уникален и вы не должны его придумывать из воздуха, а только получить из регистрации (для порождённых акторов) или его вам должен рассказать кто-то, законно его знающий.
-
-Отправка на несуществующий актор (уже умерший) безопасна, сообщение будет просто выброшено в момент обработки (как обрабатывать недоставку сообщений в протоколах расскажу ниже).
-
-Кроме нормальных TActorID существуют еще и сервисные (составленные из строчки и номера ноды). Под ними может быть зарегистрирован реальный актор и фактически при получении сообщения по сервисному адресу – попробует переправить его текущему фактическому. Это позволяет размещать хорошо известные сервисы по хорошо известному адресу, не выстраивая параллельную машинерию поиска.
-
-Строить из актора конечный автомат при помощи переключений функции-обработчика – выбор в каждом конкретном случае, иногда удобнее да, иногда сваливать всё в одно состояние, а иногда – применять гибридное решение (когда часть жизненного цикла – обычно инициализации и завершение – выражены в переходах, а часть – нет).
-Меньше слов, больше дела – этого уже достаточно что бы прочитать самый простой пример. https://a.yandex-team.ru/arc/trunk/arcadia/library/cpp/actors/examples/01_ping_pong
-Здесь можно увидеть образец самого простого актора, занимающегося переброской сообщений и использующего все основные вызовы. Заодно покрутив за разные ручки (количество тредов в тредпуле, количество пар перебрасывающихся акторов) можно посмотреть на изменение поведения системы (hint: в таких простых сценариях максимум перфоманса достигается при одном треде в тредпулах).
-
-### Event и Event Handle.
-Полезную нагрузку сообщений заворачиваем в наследника IEventBase, у которого два важных метода – сериализация и загрузка. Сериализация виртуальная, а вот загрузка – нет, и для разбора сообщения из байтовой последовательности – необходимо на стороне получателя сматчить число-идентификатор типа ивента с С++ типом. Именно это делают макросы из hfunc.h. На практике ивенты создаются либо как наследник TEventLocal<> (для строго локальных сообщений) либо как наследник TEventPB<> (для потенциально пересылаемых по сети сообщений, типизируются protobuf-мессаджем).
-
-Кроме непосредственно ивента (в виде структуры либо в виде байтовой строки) для пересылки сообщения необходим набор дополнительных полей
-
-Адресат
-
-Отправитель
-
-Тип сообщения
-
-Кука
-
-Флаги
-
-Сообщение + дополнительные поля = IEventHandle. Именно хендлами акторсистема и оперирует. <event-type>::TPtr – в примере выше – это и есть указатель на типизированный хендл.
-
-Технически типом сообщения может быть любое число, которое получатель и отправитель договорились понимать как идентификатор сообщения. Сложившаяся практика – выделять диапазон идентификаторов макросом EventSpaceBegin (фактически блоками по 64к), начиная с блока ES_USERSPACE.
-Кука – неинтерпретируемое ui64 число, передаваемое с хендлом. Хорошей практикой является в ответе сервиса на сообщение выставлять куку в куку исходного сообщения, особенно для сервисов, потенциально используемых конкурентно.
-
-В флагах несколько бит зарезервировано под флаги, декларирующие как необходимо обрабатывать особые ситуации и 12 бит – под номер канала интерконнекта, в котором будет пересылаться сообщение (для локальных сообщений в имеющихся реализациях номер канала не имеет значения - хотя можно представить реализацию где для каналов будут независимые очереди).
-
-### Тредпулы и мейлбоксы.
-В рамках одной акторсистемы может сосуществовать несколько независимых тредпулов, каждый актор регистрируется на конкретном и в процессе жизни не может мигрировать (но может создавать новые акторы на произвольном тредпуле). Используется для крупноблочного разделения ресурсов, либо между разными активностями (вот здесь – обрабатываем один класс запросов, а вот здесь - другой), либо между разными профилями активности (вот здесь обрабатываем быстрые запросы, здесь – медленные, а вот там – вообще батчёвые). Например в YDB работает системный тредпул (в котором запускаются акторы, необходимые для функционирования YDB, и для которого мы следим что бы не было длительной блокировки в обработчиках), пользовательский тредпул (в котором обрабатываются запросы и потенциально обработчики могут уходить в себя подольше, но это не повлияет на инфраструктуру), батчёвый тредпул (куда отгружается длительная обработка – компакшены дисков, сканы таблиц и подобное) и, в жирных нодах – тредпул интерконнекта (как наиболее чувствительного к задержкам).
-Пересылка сообщений между акторами разных тредпулов но одной локальной акторсистемы остаётся локальной, принудительной сериализации сообщения не происходит.
-
-При регистрации актор прикрепляется к мейлбоксу (в типичном случае на собственном мейлбоксе, но по особой нужде можно находясь внутри обработки сообщения прикрепить порождённый актор к текущему активному мейлбоксу – см. RegisterWithSameMailbox (ранее RegisterLocal) – в этом случае будет гарантироваться отсутствие конкурентной обработки сообщений). Собственно Send – это и есть заворачивание ивента в хендл, помещение хендла в очередь мейлбокса и добавление мейлбокса в очередь активации тредпула. В рамках одного мейлбокса – обработка FIFO, между мейлбоксами таких гарантий нет, хотя и стараемся активировать мейлбоксы примерно в порядке появления в них сообщений.
-
-При регистрации актора можно выбрать тип мейлбокса, они немного отличаются стоимость добавления – либо дёшево, но похуже под контеншеном, либо почти wait-free, но подороже. См. комментарии к TMailboxType за актуальными подсказками что-как.
-
-Полезные хелперы.
-
-STFUNC – декларация стейт-функции, рекомендую всегда использовать именно такую форму для декларации, т.к. потом проще искать.
-
-hFunc – макрос выбора хендлера, передающий ивент в обработчик.
-
-cFunc – макрос выбора хендлера, не передающий ивент в обработчик.
-
-### Обработка сбоев.
-В рамках локальной акторсистемы доставка сообщений гарантирована, если по какой-то причине сообщение не доставлено (важно! Именно не доставлено, факт обработанности сообщения уже на совести принимающего актора) – то произойдёт одно из:
-
-Если выставлен флаг FlagForwardOnNondelivery – сообщение будет переправлено на актор, переданный как forwardOnNondelivery при конструировании хендла. Полезно например если какие-то сервисы создаются по требованию и для несозданных сервисов – желаем зароутить в роутер. Работает только в рамках локальной акторсистемы.
-
-Иначе при выставленном флаге FlagTrackDelivery – для отправителя будет сгенерирован ивент TEvUndelivered от имени недоступного актора. Получение такого сообщения гарантирует что исходный ивент не был обработан и никакие эффекты не произошли. Генерация и доставка нотификации в рамках локальной акторсистемы гарантирована, в распределённой – как повезёт, может и потеряться.
-
-Иначе, если никакие флаги не выставлены – сообщение будет выброшено.
-
-Т.к. в распределённой системе доставка нотификаций о недоставке не гарантируется, то для надёжной обработки сбоев необходим дополнительный механизм – по флагу FlagSubscribeOnSession при пересечении границ ноды происходит подписка отправителя на нотификацию о разрыве сетевой сессии, в рамках которой сообщение было отправлено. Теперь при разрыве сетевой сессии отправитель узнает что сообщение могло быть недоставлено (а могло и быть доставлено – мы не знаем) и сможет отреагировать. Нужно не забывать отписываться от нотификации о разрыве сессий – иначе будут копиться вплоть до ближайшего разрыва (который может и не скоро произойти).
-
-Резюмируя: при необходимости контролировать доставку внутри локальной акторсистемы – выставляем флаг FlagTrackDelivery и обрабатываем TEvUndelivered. Для распределённой – добавляем FlagSubscribeOnSession и дополнительно обрабатываем TEvNodeDisconnected не забывая отписываться от более не нужных подписок.
-
-### Интерконнект.
-Локальная акторсистема – это только половина пирога, возможность объединить их в распределённую – вторая половина. Реализация интерконнекта доступна из коробки и умеет
-Передавать сообщения через одно tcp-соединение
-Мультиплексировать разные потоки (ака каналы) в рамках одного соединения, гарантируя порядок в рамках канала
-Старается делать это хорошо.
-В рамках распределённой системы требуется каждой локальной акторсистеме назначить уникальный номер (например табличкой или реализовав динамическую раздачу номеров ноды) и запустить в рамках каждой локальной акторсистемы локальный неймсервис (например по табличке ремапинга номера ноды в сетевой адрес либо как кеш опорного неймсервиса).
-Смотрим на второй пример https://a.yandex-team.ru/arcadia/library/cpp/actors/examples/02_discovery
-Тут у нас конфигурируется распределённая акторсистема (в примере все пять запускаются в одном бинарнике, но точно так же – можно запускать и частями) на пять нод. На каждой ноде запускается реплика для паблишинга строчек и актор-эндпоинт (каждый со своим портом). Эндпоинты с помощью актора-паблишера публикуют свои явки/пароли на распределённый сторадж (с обработкой нештатных ситауций и поддержанием в актуальном состоянии). И рядом лежит реализация запроса к стораджу на листинг опубликованого по мажорити. Собственно это упрощённый и почищенный от специфики код, используемый в YDB для публикации и нахождения актуальных эндпоинтов пользовательской базы.
diff --git a/library/cpp/actors/actor_type/CMakeLists.darwin-arm64.txt b/library/cpp/actors/actor_type/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 825e96d2d8..0000000000
--- a/library/cpp/actors/actor_type/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-
-add_library(cpp-actors-actor_type)
-target_link_libraries(cpp-actors-actor_type PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-util
- cpp-actors-prof
- tools-enum_parser-enum_serialization_runtime
-)
-target_sources(cpp-actors-actor_type PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/common.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/indexes.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/index_constructor.cpp
-)
-generate_enum_serilization(cpp-actors-actor_type
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/common.h
- INCLUDE_HEADERS
- library/cpp/actors/actor_type/common.h
-)
diff --git a/library/cpp/actors/actor_type/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/actor_type/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 825e96d2d8..0000000000
--- a/library/cpp/actors/actor_type/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-
-add_library(cpp-actors-actor_type)
-target_link_libraries(cpp-actors-actor_type PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-util
- cpp-actors-prof
- tools-enum_parser-enum_serialization_runtime
-)
-target_sources(cpp-actors-actor_type PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/common.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/indexes.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/index_constructor.cpp
-)
-generate_enum_serilization(cpp-actors-actor_type
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/common.h
- INCLUDE_HEADERS
- library/cpp/actors/actor_type/common.h
-)
diff --git a/library/cpp/actors/actor_type/CMakeLists.linux-aarch64.txt b/library/cpp/actors/actor_type/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index dc1ebb7a22..0000000000
--- a/library/cpp/actors/actor_type/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-
-add_library(cpp-actors-actor_type)
-target_link_libraries(cpp-actors-actor_type PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-util
- cpp-actors-prof
- tools-enum_parser-enum_serialization_runtime
-)
-target_sources(cpp-actors-actor_type PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/common.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/indexes.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/index_constructor.cpp
-)
-generate_enum_serilization(cpp-actors-actor_type
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/common.h
- INCLUDE_HEADERS
- library/cpp/actors/actor_type/common.h
-)
diff --git a/library/cpp/actors/actor_type/CMakeLists.linux-x86_64.txt b/library/cpp/actors/actor_type/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index dc1ebb7a22..0000000000
--- a/library/cpp/actors/actor_type/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-
-add_library(cpp-actors-actor_type)
-target_link_libraries(cpp-actors-actor_type PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-util
- cpp-actors-prof
- tools-enum_parser-enum_serialization_runtime
-)
-target_sources(cpp-actors-actor_type PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/common.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/indexes.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/index_constructor.cpp
-)
-generate_enum_serilization(cpp-actors-actor_type
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/common.h
- INCLUDE_HEADERS
- library/cpp/actors/actor_type/common.h
-)
diff --git a/library/cpp/actors/actor_type/CMakeLists.txt b/library/cpp/actors/actor_type/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/actor_type/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/actor_type/CMakeLists.windows-x86_64.txt b/library/cpp/actors/actor_type/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 825e96d2d8..0000000000
--- a/library/cpp/actors/actor_type/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-
-add_library(cpp-actors-actor_type)
-target_link_libraries(cpp-actors-actor_type PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-util
- cpp-actors-prof
- tools-enum_parser-enum_serialization_runtime
-)
-target_sources(cpp-actors-actor_type PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/common.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/indexes.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/index_constructor.cpp
-)
-generate_enum_serilization(cpp-actors-actor_type
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/actor_type/common.h
- INCLUDE_HEADERS
- library/cpp/actors/actor_type/common.h
-)
diff --git a/library/cpp/actors/actor_type/common.cpp b/library/cpp/actors/actor_type/common.cpp
deleted file mode 100644
index be8569b7f5..0000000000
--- a/library/cpp/actors/actor_type/common.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "common.h"
-
-namespace NActors {
-
-}
diff --git a/library/cpp/actors/actor_type/common.h b/library/cpp/actors/actor_type/common.h
deleted file mode 100644
index cfda827c3f..0000000000
--- a/library/cpp/actors/actor_type/common.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-namespace NActors {
-
-struct TActorActivityTag {};
-
-}
-
-namespace NActors {
-enum class EInternalActorType {
- OTHER = 0,
- INCORRECT_ACTOR_TYPE_INDEX,
- ACTOR_SYSTEM,
- ACTORLIB_COMMON,
- ACTORLIB_STATS,
- LOG_ACTOR,
- INTERCONNECT_PROXY_TCP,
- INTERCONNECT_SESSION_TCP,
- INTERCONNECT_COMMON,
- SELF_PING_ACTOR,
- TEST_ACTOR_RUNTIME,
- INTERCONNECT_HANDSHAKE,
- INTERCONNECT_POLLER,
- INTERCONNECT_SESSION_KILLER,
- ACTOR_SYSTEM_SCHEDULER_ACTOR,
- ACTOR_FUTURE_CALLBACK,
- INTERCONNECT_MONACTOR,
- INTERCONNECT_LOAD_ACTOR,
- INTERCONNECT_LOAD_RESPONDER,
- NAMESERVICE,
- DNS_RESOLVER,
- INTERCONNECT_PROXY_WRAPPER,
- ACTOR_COROUTINE
-};
-}
diff --git a/library/cpp/actors/actor_type/index_constructor.cpp b/library/cpp/actors/actor_type/index_constructor.cpp
deleted file mode 100644
index 667d3617c3..0000000000
--- a/library/cpp/actors/actor_type/index_constructor.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "index_constructor.h"
-
-namespace NActors {
-
-}
diff --git a/library/cpp/actors/actor_type/index_constructor.h b/library/cpp/actors/actor_type/index_constructor.h
deleted file mode 100644
index b533643a61..0000000000
--- a/library/cpp/actors/actor_type/index_constructor.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-#include "common.h"
-#include <library/cpp/actors/util/local_process_key.h>
-#include <library/cpp/actors/prof/tag.h>
-
-template <>
-class TLocalProcessKeyStateIndexConstructor<NActors::TActorActivityTag> {
-public:
- static ui32 BuildCurrentIndex(const TStringBuf name, const ui32 /*currentNamesCount*/) {
- return NProfiling::MakeTag(name.data());
- }
-};
diff --git a/library/cpp/actors/actor_type/indexes.cpp b/library/cpp/actors/actor_type/indexes.cpp
deleted file mode 100644
index 628eae08d8..0000000000
--- a/library/cpp/actors/actor_type/indexes.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "indexes.h"
-
-namespace NActors {
-
-}
diff --git a/library/cpp/actors/actor_type/indexes.h b/library/cpp/actors/actor_type/indexes.h
deleted file mode 100644
index a971847056..0000000000
--- a/library/cpp/actors/actor_type/indexes.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-#include "common.h"
-#include "index_constructor.h"
-#include <library/cpp/actors/util/local_process_key.h>
-
-namespace NActors {
-
-class TActorTypeOperator {
-public:
- static constexpr ui32 GetMaxAvailableActorsCount() {
- return TLocalProcessKeyStateIndexLimiter::GetMaxKeysCount();
- }
-
- template <class TEnum>
- static ui32 GetEnumActivityType(const TEnum enumValue) {
- return TEnumProcessKey<TActorActivityTag, TEnum>::GetIndex(enumValue);
- }
-
- static ui32 GetActorSystemIndex() {
- return TEnumProcessKey<TActorActivityTag, EInternalActorType>::GetIndex(EInternalActorType::ACTOR_SYSTEM);
- }
-
- static ui32 GetOtherActivityIndex() {
- return TEnumProcessKey<TActorActivityTag, EInternalActorType>::GetIndex(EInternalActorType::OTHER);
- }
-
- static ui32 GetActorActivityIncorrectIndex() {
- return TEnumProcessKey<TActorActivityTag, EInternalActorType>::GetIndex(EInternalActorType::INCORRECT_ACTOR_TYPE_INDEX);
- }
-};
-}
diff --git a/library/cpp/actors/actor_type/ya.make b/library/cpp/actors/actor_type/ya.make
deleted file mode 100644
index 736e99cf49..0000000000
--- a/library/cpp/actors/actor_type/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-LIBRARY()
-
-SRCS(
- common.cpp
- indexes.cpp
- index_constructor.cpp
-)
-
-PEERDIR(
- library/cpp/actors/util
- library/cpp/actors/prof
-)
-
-GENERATE_ENUM_SERIALIZATION(common.h)
-
-END()
diff --git a/library/cpp/actors/core/CMakeLists.darwin-arm64.txt b/library/cpp/actors/core/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 2090b64ba1..0000000000
--- a/library/cpp/actors/core/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-add_subdirectory(ut_fat)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-
-add_library(cpp-actors-core)
-target_link_libraries(cpp-actors-core PUBLIC
- contrib-libs-cxxsupp
- yutil
- tools-enum_parser-enum_serialization_runtime
- cpp-actors-actor_type
- cpp-actors-memory_log
- cpp-actors-prof
- cpp-actors-protos
- cpp-actors-util
- library-cpp-execprofile
- cpp-json-writer
- library-cpp-logger
- library-cpp-lwtrace
- cpp-monlib-dynamic_counters
- library-cpp-svnversion
- library-cpp-time_provider
- cpp-threading-future
-)
-target_sources(cpp-actors-core PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_bootstrapped.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_coroutine.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_virtual.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorid.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorsystem.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ask.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/av_bootstrapped.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/balancer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/buffer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/callstack.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/cpu_manager.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_load.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/events_undelivered.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_base.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_basic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_io.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_united.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_thread.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/harmonizer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/interconnect.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/io_dispatcher.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_settings.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_buffer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/mailbox.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/monotonic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/monotonic_provider.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/worker_context.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/probes.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/process_stats.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_basic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_cookie.cpp
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/defs.h
- INCLUDE_HEADERS
- library/cpp/actors/core/defs.h
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor.h
- INCLUDE_HEADERS
- library/cpp/actors/core/actor.h
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_iface.h
- INCLUDE_HEADERS
- library/cpp/actors/core/log_iface.h
-)
diff --git a/library/cpp/actors/core/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/core/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 2090b64ba1..0000000000
--- a/library/cpp/actors/core/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-add_subdirectory(ut_fat)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-
-add_library(cpp-actors-core)
-target_link_libraries(cpp-actors-core PUBLIC
- contrib-libs-cxxsupp
- yutil
- tools-enum_parser-enum_serialization_runtime
- cpp-actors-actor_type
- cpp-actors-memory_log
- cpp-actors-prof
- cpp-actors-protos
- cpp-actors-util
- library-cpp-execprofile
- cpp-json-writer
- library-cpp-logger
- library-cpp-lwtrace
- cpp-monlib-dynamic_counters
- library-cpp-svnversion
- library-cpp-time_provider
- cpp-threading-future
-)
-target_sources(cpp-actors-core PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_bootstrapped.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_coroutine.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_virtual.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorid.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorsystem.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ask.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/av_bootstrapped.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/balancer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/buffer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/callstack.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/cpu_manager.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_load.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/events_undelivered.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_base.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_basic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_io.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_united.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_thread.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/harmonizer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/interconnect.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/io_dispatcher.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_settings.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_buffer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/mailbox.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/monotonic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/monotonic_provider.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/worker_context.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/probes.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/process_stats.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_basic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_cookie.cpp
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/defs.h
- INCLUDE_HEADERS
- library/cpp/actors/core/defs.h
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor.h
- INCLUDE_HEADERS
- library/cpp/actors/core/actor.h
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_iface.h
- INCLUDE_HEADERS
- library/cpp/actors/core/log_iface.h
-)
diff --git a/library/cpp/actors/core/CMakeLists.linux-aarch64.txt b/library/cpp/actors/core/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 24152462c9..0000000000
--- a/library/cpp/actors/core/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-add_subdirectory(ut_fat)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-
-add_library(cpp-actors-core)
-target_link_libraries(cpp-actors-core PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- tools-enum_parser-enum_serialization_runtime
- cpp-actors-actor_type
- cpp-actors-memory_log
- cpp-actors-prof
- cpp-actors-protos
- cpp-actors-util
- library-cpp-execprofile
- cpp-json-writer
- library-cpp-logger
- library-cpp-lwtrace
- cpp-monlib-dynamic_counters
- library-cpp-svnversion
- library-cpp-time_provider
- cpp-threading-future
-)
-target_sources(cpp-actors-core PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_bootstrapped.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_coroutine.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_virtual.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorid.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorsystem.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ask.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/av_bootstrapped.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/balancer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/buffer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/callstack.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/cpu_manager.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_load.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/events_undelivered.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_base.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_basic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_io.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_united.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_thread.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/harmonizer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/interconnect.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/io_dispatcher.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_settings.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_buffer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/mailbox.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/monotonic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/monotonic_provider.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/worker_context.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/probes.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/process_stats.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_basic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_cookie.cpp
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/defs.h
- INCLUDE_HEADERS
- library/cpp/actors/core/defs.h
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor.h
- INCLUDE_HEADERS
- library/cpp/actors/core/actor.h
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_iface.h
- INCLUDE_HEADERS
- library/cpp/actors/core/log_iface.h
-)
diff --git a/library/cpp/actors/core/CMakeLists.linux-x86_64.txt b/library/cpp/actors/core/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 24152462c9..0000000000
--- a/library/cpp/actors/core/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,102 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-add_subdirectory(ut_fat)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-
-add_library(cpp-actors-core)
-target_link_libraries(cpp-actors-core PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- tools-enum_parser-enum_serialization_runtime
- cpp-actors-actor_type
- cpp-actors-memory_log
- cpp-actors-prof
- cpp-actors-protos
- cpp-actors-util
- library-cpp-execprofile
- cpp-json-writer
- library-cpp-logger
- library-cpp-lwtrace
- cpp-monlib-dynamic_counters
- library-cpp-svnversion
- library-cpp-time_provider
- cpp-threading-future
-)
-target_sources(cpp-actors-core PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_bootstrapped.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_coroutine.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_virtual.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorid.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorsystem.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ask.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/av_bootstrapped.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/balancer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/buffer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/callstack.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/cpu_manager.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_load.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/events_undelivered.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_base.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_basic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_io.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_united.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_thread.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/harmonizer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/interconnect.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/io_dispatcher.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_settings.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_buffer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/mailbox.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/monotonic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/monotonic_provider.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/worker_context.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/probes.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/process_stats.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_basic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_cookie.cpp
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/defs.h
- INCLUDE_HEADERS
- library/cpp/actors/core/defs.h
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor.h
- INCLUDE_HEADERS
- library/cpp/actors/core/actor.h
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_iface.h
- INCLUDE_HEADERS
- library/cpp/actors/core/log_iface.h
-)
diff --git a/library/cpp/actors/core/CMakeLists.txt b/library/cpp/actors/core/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/core/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/core/CMakeLists.windows-x86_64.txt b/library/cpp/actors/core/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 2090b64ba1..0000000000
--- a/library/cpp/actors/core/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-add_subdirectory(ut_fat)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-get_built_tool_path(
- TOOL_enum_parser_bin
- TOOL_enum_parser_dependency
- tools/enum_parser/enum_parser
- enum_parser
-)
-
-add_library(cpp-actors-core)
-target_link_libraries(cpp-actors-core PUBLIC
- contrib-libs-cxxsupp
- yutil
- tools-enum_parser-enum_serialization_runtime
- cpp-actors-actor_type
- cpp-actors-memory_log
- cpp-actors-prof
- cpp-actors-protos
- cpp-actors-util
- library-cpp-execprofile
- cpp-json-writer
- library-cpp-logger
- library-cpp-lwtrace
- cpp-monlib-dynamic_counters
- library-cpp-svnversion
- library-cpp-time_provider
- cpp-threading-future
-)
-target_sources(cpp-actors-core PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_bootstrapped.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_coroutine.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_virtual.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorid.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorsystem.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ask.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/av_bootstrapped.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/balancer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/buffer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/callstack.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/cpu_manager.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_load.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/events_undelivered.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_base.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_basic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_io.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_united.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_thread.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/harmonizer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/interconnect.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/io_dispatcher.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_settings.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_buffer.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/mailbox.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/monotonic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/monotonic_provider.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/worker_context.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/probes.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/process_stats.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_basic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_cookie.cpp
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/defs.h
- INCLUDE_HEADERS
- library/cpp/actors/core/defs.h
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor.h
- INCLUDE_HEADERS
- library/cpp/actors/core/actor.h
-)
-generate_enum_serilization(cpp-actors-core
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_iface.h
- INCLUDE_HEADERS
- library/cpp/actors/core/log_iface.h
-)
diff --git a/library/cpp/actors/core/README.md b/library/cpp/actors/core/README.md
deleted file mode 100644
index cb5fb9dfbd..0000000000
--- a/library/cpp/actors/core/README.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# ActorSystem
-
-## Sending
-
-Обычная отправка (Send) сообщения проходит следующим образом:
-
-1) По получателю находится MailBox
-2) Кладется сообщение в мейлбокс
-3) Проверяется единсвенное ли это сообщение в мейлбоксе, если нет, то больше ничего не делаем
-4) Иначе кладем сообщение в очередь активаций и в случае наличия спящих потоков, будим один из них
-
-Из этого следует, что мы всегда стараемся будить поток.
-Например если 2 актора пересылают друг другу сообщение, то они будут по переменно работать в разных потоках.
-
-Но они вполне могли бы работать на одном потоке, и скорее всего это бы работало эффективней:
-
-* Кеши не теряются из перехода с одного потока на другой.
-* Меньше затрат на пробуждение потоков.
-
-Для этого сделали два других способа отправки Send<ESendingType::Lazy> и Send<ESendingType::Tail>
-
-Send<ESendingType::Lazy> старается придержать мейлбокс в который отправили сообщение, до окончания обработки текущего мейлбокса и работае следующим образом:
-
-1) По получателю находится MailBox
-2) Кладется сообщение в мейлбокс
-3) Проверяется единсвенное ли это сообщение в мейлбоксе, если нет, то больше ничего не делаем
-4) Захватываем мейлбокс
-5) Если до этого уже захватили мейлбокс, то старый кладется в очередь активаций и пробуем разбудить спящий поток
-6) После завершения обработки текущего мейлбокса проверяется, есть ли активация в очереди активаций. Если есть, то берем из очереди активаций мейлбокс, а захваченный кладем в очередь активаций, если же очередь активаций была пустая, то обрабатываем захваченный мейлбокс
-
-Из плюсов, может лишний раз не будить поток и обрабатывать сообщения в том же потоке.
-
-Из минусов, если после использования Send<ESendingType::Lazy> текущий мейлбокс будет долго обрабатываться, то это время добавиться к времени ожидания отправленного сообщения. Так как его мейлбокс захвачен потоком и не обрабатывается. Так же при сильной загрузки системы, когда очередь активаций всегда большая, отправленным сообщения будет добавляться летенси, так как мы не сразу отправляем сообщение, а ждем пока обработка мейлбокса закончится. И так как очередь акттиваций всегда не пустая, то мы с задержкой кладем мейлбокс в очередь активаций, хотя могли сделать это сразу.
-
-Стоит использоваться желательно перед смертью актора, когда известно что больше он ничего обрабатывать не будет.
-
-Для случаев, когда мы не хотим ждать окончания обработки мейлбокса или смерти актора, и хотим гарантировано обработать отправленное сообщение в том же потоке, следует использовать Send<ESendingType::Tail>.
-
-После обработки текущего сообщение, обработка мейлбокса прервется, и начнется обработка захваченного мейлбокса. При этом передается квота с которым обрабатывался первый мейлбокс. Благодаря этому не получится заблокировать поток двумя акторами пересылающими друг другу сообщения. В какой-то момент кончится квота по времени или по количеству обработанных сообщений.
-
-Send<ESendingType::Tail> работает следующим образом:
-
-1) По получателю находится MailBox
-2) Кладется сообщение в мейлбокс
-3) Проверяется единсвенное ли это сообщение в мейлбоксе, если нет, то больше ничего не делаем
-4) Захватываем мейлбоксa
-5) Все остальные отправки сообщений будут работать как обычный Send
-6) После завершения обработки текущего сообщения, прерывается обработка мейлбокса и начинается обработка захваченного мейлбокса с квотой старого мейлбокса
-7) При завершении квоты, захваченный мейлбокс обрабатывается как в Send<ESendingType::Lazy>
-
-Требуется когда важно продолжить цепочку работы в следующем акторе пока кеши сообщения еще прогреты. По сравнению с Send<ESendingType::Lazy> гарантировано продолжит обработку сообщения и не имеет проблем с задержкой обработки сообщения.
diff --git a/library/cpp/actors/core/actor.cpp b/library/cpp/actors/core/actor.cpp
deleted file mode 100644
index 6d6c92f431..0000000000
--- a/library/cpp/actors/core/actor.cpp
+++ /dev/null
@@ -1,250 +0,0 @@
-#include "actor.h"
-#include "actor_virtual.h"
-#include "actorsystem.h"
-#include "executor_thread.h"
-#include <library/cpp/actors/util/datetime.h>
-
-namespace NActors {
- Y_POD_THREAD(TThreadContext*) TlsThreadContext(nullptr);
- thread_local TActivationContext *TActivationContextHolder::Value = nullptr;
- TActivationContextHolder TlsActivationContext;
-
- [[gnu::noinline]] TActivationContextHolder::operator bool() const {
- asm volatile("");
- return Value != nullptr;
- }
-
- [[gnu::noinline]] TActivationContextHolder::operator TActivationContext*() const {
- asm volatile("");
- return Value;
- }
-
- [[gnu::noinline]] TActivationContext *TActivationContextHolder::operator ->() {
- asm volatile("");
- return Value;
- }
-
- [[gnu::noinline]] TActivationContext& TActivationContextHolder::operator *() {
- asm volatile("");
- return *Value;
- }
-
- [[gnu::noinline]] TActivationContextHolder& TActivationContextHolder::operator =(TActivationContext *context) {
- asm volatile("");
- Value = context;
- return *this;
- }
-
- template<i64 Increment>
- static void UpdateQueueSizeAndTimestamp(TActorUsageImpl<true>& impl, ui64 time) {
- ui64 usedTimeIncrement = 0;
- using T = TActorUsageImpl<true>;
-
- for (;;) {
- uint64_t value = impl.QueueSizeAndTimestamp.load();
- ui64 count = value >> T::TimestampBits;
-
- count += Increment;
- Y_ABORT_UNLESS((count & ~T::CountMask) == 0);
-
- ui64 timestamp = value;
- if (Increment == 1 && count == 1) {
- timestamp = time;
- } else if (Increment == -1 && count == 0) {
- usedTimeIncrement = (static_cast<ui64>(time) - timestamp) & T::TimestampMask;
- timestamp = 0; // reset timestamp to some zero value
- }
-
- const ui64 updated = (timestamp & T::TimestampMask) | (count << T::TimestampBits);
- if (impl.QueueSizeAndTimestamp.compare_exchange_weak(value, updated)) {
- break;
- }
- }
-
- if (usedTimeIncrement && impl.LastUsageTimestamp <= time) {
- impl.UsedTime += usedTimeIncrement;
- }
- }
-
- void TActorUsageImpl<true>::OnEnqueueEvent(ui64 time) {
- UpdateQueueSizeAndTimestamp<+1>(*this, time);
- }
-
- void TActorUsageImpl<true>::OnDequeueEvent() {
- UpdateQueueSizeAndTimestamp<-1>(*this, GetCycleCountFast());
- }
-
- double TActorUsageImpl<true>::GetUsage(ui64 time) {
- ui64 used = UsedTime.exchange(0);
- if (const ui64 value = QueueSizeAndTimestamp.load(); value >> TimestampBits) {
- used += (static_cast<ui64>(time) - value) & TimestampMask;
- }
-
- Y_ABORT_UNLESS(LastUsageTimestamp <= time);
- ui64 passed = time - LastUsageTimestamp;
- LastUsageTimestamp = time;
-
- if (!passed) {
- return 0;
- }
-
- return (double)Min(passed, used) / passed;
- }
-
- void IActor::Describe(IOutputStream &out) const noexcept {
- SelfActorId.Out(out);
- }
-
- bool IActor::Send(TAutoPtr<IEventHandle> ev) const noexcept {
- return TActivationContext::Send(ev);
- }
-
- bool IActor::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const noexcept {
- return SelfActorId.Send(recipient, ev, flags, cookie, std::move(traceId));
- }
-
- void TActivationContext::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) {
- TlsActivationContext->ExecutorThread.Schedule(deadline, ev, cookie);
- }
-
- void TActivationContext::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) {
- TlsActivationContext->ExecutorThread.Schedule(deadline, ev, cookie);
- }
-
- void TActivationContext::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) {
- TlsActivationContext->ExecutorThread.Schedule(delta, 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_DEBUG_ABORT_UNLESS(parentId);
- auto& ctx = *TlsActivationContext;
- return ctx.ExecutorThread.RegisterActor(actor, &ctx.Mailbox, parentId.Hint(), parentId);
- }
-
- TActorId TActorContext::RegisterWithSameMailbox(IActor* actor) const {
- return ExecutorThread.RegisterActor(actor, &Mailbox, SelfID.Hint(), SelfID);
- }
-
- TActorId IActor::RegisterWithSameMailbox(IActor* actor) const noexcept {
- return TlsActivationContext->ExecutorThread.RegisterActor(actor, &TlsActivationContext->Mailbox, SelfActorId.Hint(), SelfActorId);
- }
-
- TActorId TActivationContext::InterconnectProxy(ui32 destinationNodeId) {
- return TlsActivationContext->ExecutorThread.ActorSystem->InterconnectProxy(destinationNodeId);
- }
-
- TActorSystem* TActivationContext::ActorSystem() {
- return TlsActivationContext->ExecutorThread.ActorSystem;
- }
-
- i64 TActivationContext::GetCurrentEventTicks() {
- return GetCycleCountFast() - TlsActivationContext->EventStart;
- }
-
- double TActivationContext::GetCurrentEventTicksAsSeconds() {
- return NHPTimer::GetSeconds(GetCurrentEventTicks());
- }
-
- TActorId IActor::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) const noexcept {
- return TlsActivationContext->ExecutorThread.RegisterActor(actor, mailboxType, poolId, SelfActorId);
- }
-
- void TActorContext::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const {
- ExecutorThread.Schedule(deadline, new IEventHandle(SelfID, TActorId(), ev), cookie);
- }
-
- void TActorContext::Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie) const {
- ExecutorThread.Schedule(deadline, new IEventHandle(SelfID, TActorId(), ev), cookie);
- }
-
- void TActorContext::Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie) const {
- ExecutorThread.Schedule(delta, new IEventHandle(SelfID, TActorId(), ev), cookie);
- }
-
- void IActor::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const noexcept {
- TlsActivationContext->ExecutorThread.Schedule(deadline, new IEventHandle(SelfActorId, TActorId(), ev), cookie);
- }
-
- void IActor::Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie) const noexcept {
- TlsActivationContext->ExecutorThread.Schedule(deadline, new IEventHandle(SelfActorId, TActorId(), ev), cookie);
- }
-
- void IActor::Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie) const noexcept {
- TlsActivationContext->ExecutorThread.Schedule(delta, new IEventHandle(SelfActorId, TActorId(), ev), cookie);
- }
-
- TInstant TActivationContext::Now() {
- return TlsActivationContext->ExecutorThread.ActorSystem->Timestamp();
- }
-
- TMonotonic TActivationContext::Monotonic() {
- 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();
- }
-
- std::pair<ui32, ui32> TActorContext::CountMailboxEvents(ui32 maxTraverse) const {
- return Mailbox.CountMailboxEvents(SelfID.LocalId(), maxTraverse);
- }
-
- std::pair<ui32, ui32> IActor::CountMailboxEvents(ui32 maxTraverse) const {
- return TlsActivationContext->Mailbox.CountMailboxEvents(SelfActorId.LocalId(), maxTraverse);
- }
-
- void IActor::Die(const TActorContext& ctx) {
- if (ctx.SelfID)
- Y_ABORT_UNLESS(ctx.SelfID == SelfActorId);
- PassAway();
- }
-
- void IActor::PassAway() {
- auto& cx = *TlsActivationContext;
- cx.ExecutorThread.UnregisterActor(&cx.Mailbox, SelfActorId);
- }
-
- double IActor::GetElapsedTicksAsSeconds() const {
- return NHPTimer::GetSeconds(ElapsedTicks);
- }
-
- void TActorCallbackBehaviour::Receive(IActor* actor, TAutoPtr<IEventHandle>& ev) {
- (actor->*StateFunc)(ev);
- }
-
- void TActorVirtualBehaviour::Receive(IActor* actor, std::unique_ptr<IEventHandle> ev) {
- Y_ABORT_UNLESS(!!ev && ev->GetBase());
- ev->GetBase()->Execute(actor, std::move(ev));
- }
-
- void IActor::Registered(TActorSystem* sys, const TActorId& owner) {
- // fallback to legacy method, do not use it anymore
- if (auto eh = AfterRegister(SelfId(), owner)) {
- if (!TlsThreadContext || TlsThreadContext->SendingType == ESendingType::Common) {
- sys->Send(eh);
- } else {
- sys->SpecificSend(eh);
- }
- }
- }
-}
diff --git a/library/cpp/actors/core/actor.h b/library/cpp/actors/core/actor.h
deleted file mode 100644
index 96a8f5d05a..0000000000
--- a/library/cpp/actors/core/actor.h
+++ /dev/null
@@ -1,999 +0,0 @@
-#pragma once
-
-#include "actorsystem.h"
-#include "event.h"
-#include "executor_thread.h"
-#include "monotonic.h"
-#include "thread_context.h"
-
-#include <library/cpp/actors/actor_type/indexes.h>
-#include <library/cpp/actors/util/local_process_key.h>
-
-#include <util/system/tls.h>
-#include <util/generic/noncopyable.h>
-
-namespace NActors {
- class TActorSystem;
- class TMailboxTable;
- struct TMailboxHeader;
-
- class TExecutorThread;
- class IActor;
- class ISchedulerCookie;
- class IExecutorPool;
-
- namespace NLog {
- struct TSettings;
- }
-
- struct TActorContext;
- struct TActivationContext;
-
- class TActivationContextHolder {
- static thread_local TActivationContext *Value;
-
- public:
- [[gnu::noinline]] operator bool() const;
- [[gnu::noinline]] operator TActivationContext*() const;
- [[gnu::noinline]] TActivationContext *operator ->();
- [[gnu::noinline]] TActivationContext& operator *();
- [[gnu::noinline]] TActivationContextHolder& operator=(TActivationContext *context);
- };
-
- extern TActivationContextHolder TlsActivationContext;
-
- struct TActivationContext {
- public:
- TMailboxHeader& Mailbox;
- TExecutorThread& ExecutorThread;
- const NHPTimer::STime EventStart;
-
- protected:
- explicit TActivationContext(TMailboxHeader& mailbox, TExecutorThread& executorThread, NHPTimer::STime eventStart)
- : Mailbox(mailbox)
- , ExecutorThread(executorThread)
- , EventStart(eventStart)
- {
- }
-
- public:
- template <ESendingType SendingType = ESendingType::Common>
- static bool Send(TAutoPtr<IEventHandle> ev);
-
- template <ESendingType SendingType = ESendingType::Common>
- static bool Send(std::unique_ptr<IEventHandle> &&ev);
-
- template <ESendingType SendingType = ESendingType::Common>
- static bool Forward(TAutoPtr<IEventHandle>& ev, const TActorId& recipient);
-
- template <ESendingType SendingType = ESendingType::Common>
- static bool Forward(THolder<IEventHandle>& ev, const TActorId& recipient);
-
- /**
- * Schedule one-shot event that will be send at given time point in the future.
- *
- * @param deadline the wallclock time point in future when event must be send
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- static void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr);
- static void Schedule(TInstant deadline, std::unique_ptr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) {
- return Schedule(deadline, TAutoPtr<IEventHandle>(ev.release()), cookie);
- }
-
- /**
- * Schedule one-shot event that will be send at given time point in the future.
- *
- * @param deadline the monotonic time point in future when event must be send
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- static void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr);
- static void Schedule(TMonotonic deadline, std::unique_ptr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) {
- return Schedule(deadline, TAutoPtr<IEventHandle>(ev.release()), cookie);
- }
-
- /**
- * Schedule one-shot event that will be send after given delay.
- *
- * @param delta the time from now to delay event sending
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- static void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr);
- static void Schedule(TDuration delta, std::unique_ptr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) {
- return Schedule(delta, TAutoPtr<IEventHandle>(ev.release()), cookie);
- }
-
- static TInstant Now();
- static TMonotonic Monotonic();
- NLog::TSettings* LoggerSettings() const;
-
- // register new actor in ActorSystem on new fresh mailbox.
- template <ESendingType SendingType = ESendingType::Common>
- 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
- // no _cpu core scalability_ for such actors.
- // This method of registration can be usefull if multiple actors share
- // some memory.
- static TActorId RegisterWithSameMailbox(IActor* actor, TActorId parentId);
-
- static const TActorContext& AsActorContext();
- static TActorContext ActorContextFor(TActorId id);
-
- static TActorId InterconnectProxy(ui32 nodeid);
- static TActorSystem* ActorSystem();
-
- static i64 GetCurrentEventTicks();
- static double GetCurrentEventTicksAsSeconds();
- };
-
- struct TActorContext: public TActivationContext {
- const TActorId SelfID;
- using TEventFlags = IEventHandle::TEventFlags;
- explicit TActorContext(TMailboxHeader& mailbox, TExecutorThread& executorThread, NHPTimer::STime eventStart, const TActorId& selfID)
- : TActivationContext(mailbox, executorThread, eventStart)
- , SelfID(selfID)
- {
- }
-
- template <ESendingType SendingType = ESendingType::Common>
- bool Send(const TActorId& recipient, IEventBase* ev, TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const;
- template <ESendingType SendingType = ESendingType::Common>
- bool Send(const TActorId& recipient, THolder<IEventBase> ev, TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const {
- return Send<SendingType>(recipient, ev.Release(), flags, cookie, std::move(traceId));
- }
- template <ESendingType SendingType = ESendingType::Common>
- bool Send(const TActorId& recipient, std::unique_ptr<IEventBase> ev, TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const {
- return Send<SendingType>(recipient, ev.release(), flags, cookie, std::move(traceId));
- }
- template <ESendingType SendingType = ESendingType::Common>
- bool Send(TAutoPtr<IEventHandle> ev) const;
- template <ESendingType SendingType = ESendingType::Common>
- bool Send(std::unique_ptr<IEventHandle> &&ev) const {
- return Send<SendingType>(TAutoPtr<IEventHandle>(ev.release()));
- }
- template <ESendingType SendingType = ESendingType::Common>
- bool Forward(TAutoPtr<IEventHandle>& ev, const TActorId& recipient) const;
- template <ESendingType SendingType = ESendingType::Common>
- bool Forward(THolder<IEventHandle>& ev, const TActorId& recipient) const;
-
- TInstant Now() const;
- TMonotonic Monotonic() const;
-
- /**
- * Schedule one-shot event that will be send at given time point in the future.
- *
- * @param deadline the wallclock time point in future when event must be send
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const;
-
- /**
- * Schedule one-shot event that will be send at given time point in the future.
- *
- * @param deadline the monotonic time point in future when event must be send
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const;
-
- /**
- * Schedule one-shot event that will be send after given delay.
- *
- * @param delta the time from now to delay event sending
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const;
-
- TActorContext MakeFor(const TActorId& otherId) const {
- return TActorContext(Mailbox, ExecutorThread, EventStart, otherId);
- }
-
- // register new actor in ActorSystem on new fresh mailbox.
- template <ESendingType SendingType = ESendingType::Common>
- TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const;
-
- // Register new actor in ActorSystem on same _mailbox_ as current actor.
- // There is one thread per mailbox to execute actor, which mean
- // no _cpu core scalability_ for such actors.
- // This method of registration can be usefull if multiple actors share
- // some memory.
- TActorId RegisterWithSameMailbox(IActor* actor) const;
-
- std::pair<ui32, ui32> CountMailboxEvents(ui32 maxTraverse = Max<ui32>()) const;
- };
-
- struct TActorIdentity: public TActorId {
- using TEventFlags = IEventHandle::TEventFlags;
- explicit TActorIdentity(TActorId actorId)
- : TActorId(actorId)
- {
- }
-
- void operator=(TActorId actorId) {
- *this = TActorIdentity(actorId);
- }
-
- template <ESendingType SendingType = ESendingType::Common>
- bool Send(const TActorId& recipient, IEventBase* ev, TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const;
- bool SendWithContinuousExecution(const TActorId& recipient, IEventBase* ev, TEventFlags 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;
- };
-
- class IActor;
-
- class IActorOps : TNonCopyable {
- public:
- virtual void Describe(IOutputStream&) const noexcept = 0;
- virtual bool Send(const TActorId& recipient, IEventBase*, IEventHandle::TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const noexcept = 0;
-
- /**
- * Schedule one-shot event that will be send at given time point in the future.
- *
- * @param deadline the wallclock time point in future when event must be send
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- virtual void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept = 0;
-
- /**
- * Schedule one-shot event that will be send at given time point in the future.
- *
- * @param deadline the monotonic time point in future when event must be send
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- virtual void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept = 0;
-
- /**
- * Schedule one-shot event that will be send after given delay.
- *
- * @param delta the time from now to delay event sending
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- virtual void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept = 0;
-
- virtual TActorId Register(IActor*, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const noexcept = 0;
- virtual TActorId RegisterWithSameMailbox(IActor*) const noexcept = 0;
- };
-
- class TDecorator;
-
- class TActorVirtualBehaviour {
- public:
- static void Receive(IActor* actor, std::unique_ptr<IEventHandle> ev);
- public:
- };
-
- class TActorCallbackBehaviour {
- private:
- using TBase = IActor;
- friend class TDecorator;
- public:
- using TReceiveFunc = void (IActor::*)(TAutoPtr<IEventHandle>& ev);
- private:
- TReceiveFunc StateFunc = nullptr;
- public:
- TActorCallbackBehaviour() = default;
- TActorCallbackBehaviour(TReceiveFunc stateFunc)
- : StateFunc(stateFunc) {
- }
- bool Initialized() const {
- return !!StateFunc;
- }
-
- // NOTE: exceptions must not escape state function but if an exception hasn't be caught
- // by the actor then we want to crash an see the stack
- void Receive(IActor* actor, TAutoPtr<IEventHandle>& ev);
-
- template <typename T>
- void Become(T stateFunc) {
- StateFunc = static_cast<TReceiveFunc>(stateFunc);
- }
-
- 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)...);
- }
-
- TReceiveFunc CurrentStateFunc() const {
- return StateFunc;
- }
-
- };
-
- template<bool>
- struct TActorUsageImpl {
- void OnEnqueueEvent(ui64 /*time*/) {} // called asynchronously when event is put in the mailbox
- void OnDequeueEvent() {} // called when processed by Executor
- double GetUsage(ui64 /*time*/) { return 0; } // called from collector thread
- void DoActorInit() {}
- };
-
- template<>
- struct TActorUsageImpl<true> {
- static constexpr int TimestampBits = 40;
- static constexpr int CountBits = 24;
- static constexpr ui64 TimestampMask = ((ui64)1 << TimestampBits) - 1;
- static constexpr ui64 CountMask = ((ui64)1 << CountBits) - 1;
-
- std::atomic_uint64_t QueueSizeAndTimestamp = 0;
- std::atomic_uint64_t UsedTime = 0; // how much time did we consume since last GetUsage() call
- ui64 LastUsageTimestamp = 0; // when GetUsage() was called the last time
-
- void OnEnqueueEvent(ui64 time);
- void OnDequeueEvent();
- double GetUsage(ui64 time);
- void DoActorInit() { LastUsageTimestamp = GetCycleCountFast(); }
- };
-
- class IActor
- : protected IActorOps
- , public TActorUsageImpl<ActorLibCollectUsageStats>
- {
- private:
- TActorIdentity SelfActorId;
- i64 ElapsedTicks;
- friend void DoActorInit(TActorSystem*, IActor*, const TActorId&, const TActorId&);
- friend class TDecorator;
-
- private: // stuck actor monitoring
- TMonotonic LastReceiveTimestamp;
- size_t StuckIndex = Max<size_t>();
- friend class TExecutorPoolBaseMailboxed;
- friend class TExecutorThread;
-
- IActor(const ui32 activityType)
- : SelfActorId(TActorId())
- , ElapsedTicks(0)
- , ActivityType(activityType)
- , HandledEvents(0) {
- }
-
- protected:
- TActorCallbackBehaviour CImpl;
- public:
- using TEventFlags = IEventHandle::TEventFlags;
- using TReceiveFunc = TActorCallbackBehaviour::TReceiveFunc;
- /// @sa services.proto NKikimrServices::TActivity::EType
- using EActorActivity = EInternalActorType;
- using EActivityType = EActorActivity;
- ui32 ActivityType;
-
- protected:
- ui64 HandledEvents;
-
- template <typename EEnum = EActivityType, typename std::enable_if<std::is_enum<EEnum>::value, bool>::type v = true>
- IActor(const EEnum activityEnumType = EActivityType::OTHER)
- : IActor(TEnumProcessKey<TActorActivityTag, EEnum>::GetIndex(activityEnumType)) {
- }
-
- IActor(TActorCallbackBehaviour&& cImpl, const ui32 activityType)
- : SelfActorId(TActorId())
- , ElapsedTicks(0)
- , CImpl(std::move(cImpl))
- , ActivityType(activityType)
- , HandledEvents(0)
- {
- }
-
- template <typename EEnum = EActivityType, typename std::enable_if<std::is_enum<EEnum>::value, bool>::type v = true>
- IActor(TActorCallbackBehaviour&& cImpl, const EEnum activityEnumType = EActivityType::OTHER)
- : IActor(std::move(cImpl), TEnumProcessKey<TActorActivityTag, EEnum>::GetIndex(activityEnumType)) {
- }
-
- public:
- template <class TEventBase>
- class TEventSenderFromActor: ::TNonCopyable {
- private:
- TEventFlags Flags = 0;
- ui64 Cookie = 0;
- const TActorIdentity SenderId;
- NWilson::TTraceId TraceId = {};
- std::unique_ptr<TEventBase> Event;
- public:
- template <class... Types>
- TEventSenderFromActor(const IActor* owner, Types&&... args)
- : SenderId(owner->SelfId())
- , Event(new TEventBase(std::forward<Types>(args)...)) {
-
- }
-
- TEventSenderFromActor& SetFlags(const TEventFlags flags) {
- Flags = flags;
- return *this;
- }
-
- TEventSenderFromActor& SetCookie(const ui64 value) {
- Cookie = value;
- return *this;
- }
-
- TEventSenderFromActor& SetTraceId(NWilson::TTraceId&& value) {
- TraceId = std::move(value);
- return *this;
- }
-
- bool SendTo(const TActorId& recipient) {
- return SenderId.Send(recipient, Event.release(), Flags, Cookie, std::move(TraceId));
- }
- };
-
- template <class TEvent, class... Types>
- TEventSenderFromActor<TEvent> Sender(Types&&... args) const {
- return TEventSenderFromActor<TEvent>(this, std::forward<Types>(args)...);
- }
-
- virtual ~IActor() {
- } // must not be called for registered actors, see Die method instead
-
- protected:
- virtual void Die(const TActorContext& ctx); // would unregister actor so call exactly once and only from inside of message processing
- virtual void PassAway();
-
- protected:
- void SetActivityType(ui32 activityType) {
- ActivityType = activityType;
- }
-
- public:
- class TPassAwayGuard: TMoveOnly {
- private:
- IActor* Owner = nullptr;
- public:
- TPassAwayGuard(TPassAwayGuard&& item) {
- Owner = item.Owner;
- item.Owner = nullptr;
- }
-
- TPassAwayGuard(IActor* owner)
- : Owner(owner)
- {
-
- }
-
- ~TPassAwayGuard() {
- if (Owner) {
- Owner->PassAway();
- }
- }
- };
-
- TPassAwayGuard PassAwayGuard() {
- return TPassAwayGuard(this);
- }
-
- // must be called to wrap any call trasitions from one actor to another
- template<typename TActor, typename TMethod, typename... TArgs>
- static std::invoke_result_t<TMethod, TActor, TArgs...> InvokeOtherActor(TActor& actor, TMethod&& method, TArgs&&... args) {
- struct TRecurseContext : TActorContext {
- TActivationContext* const Prev;
-
- TRecurseContext(const TActorId& actorId)
- : TActorContext(TActivationContext::ActorContextFor(actorId))
- , Prev(TlsActivationContext)
- {
- TlsActivationContext = this;
- }
-
- ~TRecurseContext() {
- Y_ABORT_UNLESS(TlsActivationContext == this, "TlsActivationContext mismatch; probably InvokeOtherActor was invoked from a coroutine");
- TlsActivationContext = Prev;
- }
- } context(actor.SelfId());
-
- return std::invoke(std::forward<TMethod>(method), actor, std::forward<TArgs>(args)...);
- }
-
- virtual void Registered(TActorSystem* sys, const TActorId& owner);
-
- virtual TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) {
- Y_UNUSED(self);
- Y_UNUSED(parentId);
- return TAutoPtr<IEventHandle>();
- }
-
- i64 GetElapsedTicks() const {
- return ElapsedTicks;
- }
- double GetElapsedTicksAsSeconds() const;
- void AddElapsedTicks(i64 ticks) {
- ElapsedTicks += ticks;
- }
- ui32 GetActivityType() const {
- return ActivityType;
- }
- ui64 GetHandledEvents() const {
- return HandledEvents;
- }
- TActorIdentity SelfId() const {
- return SelfActorId;
- }
-
- void Receive(TAutoPtr<IEventHandle>& ev) {
- ++HandledEvents;
- LastReceiveTimestamp = TActivationContext::Monotonic();
- if (CImpl.Initialized()) {
- CImpl.Receive(this, ev);
- } else {
- TActorVirtualBehaviour::Receive(this, std::unique_ptr<IEventHandle>(ev.Release()));
- }
- }
-
- TActorContext ActorContext() const {
- return TActivationContext::ActorContextFor(SelfId());
- }
-
- protected:
- void SetEnoughCpu(bool isEnough) {
- if (TlsThreadContext) {
- TlsThreadContext->IsEnoughCpu = isEnough;
- }
- }
-
- void Describe(IOutputStream&) const noexcept override;
- bool Send(TAutoPtr<IEventHandle> ev) const noexcept;
- bool Send(const TActorId& recipient, IEventBase* ev, TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const noexcept final;
- bool Send(const TActorId& recipient, THolder<IEventBase> ev, TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const{
- return Send(recipient, ev.Release(), flags, cookie, std::move(traceId));
- }
- bool Send(const TActorId& recipient, std::unique_ptr<IEventBase> ev, TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const {
- return Send(recipient, ev.release(), flags, cookie, std::move(traceId));
- }
-
- template <class TEvent, class ... TEventArgs>
- bool Send(TActorId recipient, TEventArgs&& ... args) const {
- return Send(recipient, MakeHolder<TEvent>(std::forward<TEventArgs>(args)...));
- }
-
- template <ESendingType SendingType>
- bool Send(const TActorId& recipient, IEventBase* ev, TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const;
- template <ESendingType SendingType>
- bool Send(const TActorId& recipient, THolder<IEventBase> ev, TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const {
- return Send(recipient, ev.Release(), flags, cookie, std::move(traceId));
- }
- template <ESendingType SendingType>
- bool Send(const TActorId& recipient, std::unique_ptr<IEventBase> ev, TEventFlags flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const {
- return Send(recipient, ev.release(), flags, cookie, std::move(traceId));
- }
-
- static bool Forward(TAutoPtr<IEventHandle>& ev, const TActorId& recipient) {
- return TActivationContext::Forward(ev, recipient);
- }
-
- static bool Forward(THolder<IEventHandle>& ev, const TActorId& recipient) {
- return TActivationContext::Forward(ev, recipient);
- }
-
- template <typename TEventHandle>
- static bool Forward(TAutoPtr<TEventHandle>& ev, const TActorId& recipient) {
- TAutoPtr<IEventHandle> evi(ev.Release());
- return TActivationContext::Forward(evi, recipient);
- }
-
- void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept final;
- void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept final;
- void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept final;
-
- // register new actor in ActorSystem on new fresh mailbox.
- TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const noexcept final;
-
- template <ESendingType SendingType>
- TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const noexcept;
-
- // Register new actor in ActorSystem on same _mailbox_ as current actor.
- // There is one thread per mailbox to execute actor, which mean
- // no _cpu core scalability_ for such actors.
- // This method of registration can be useful if multiple actors share
- // some memory.
- TActorId RegisterWithSameMailbox(IActor* actor) const noexcept final;
-
- std::pair<ui32, ui32> CountMailboxEvents(ui32 maxTraverse = Max<ui32>()) const;
-
- private:
- void ChangeSelfId(TActorId actorId) {
- SelfActorId = actorId;
- }
- };
-
- inline size_t GetActivityTypeCount() {
- return TLocalProcessKeyState<TActorActivityTag>::GetInstance().GetCount();
- }
-
- inline TStringBuf GetActivityTypeName(size_t index) {
- return TLocalProcessKeyState<TActorActivityTag>::GetInstance().GetNameByIndex(index);
- }
-
- class IActorCallback: public IActor {
- protected:
- template <class TEnum = IActor::EActivityType>
- IActorCallback(TReceiveFunc stateFunc, const TEnum activityType = IActor::EActivityType::OTHER)
- : IActor(TActorCallbackBehaviour(stateFunc), activityType) {
-
- }
-
- IActorCallback(TReceiveFunc stateFunc, const ui32 activityType)
- : IActor(TActorCallbackBehaviour(stateFunc), activityType) {
-
- }
-
- public:
- template <typename T>
- void Become(T stateFunc) {
- CImpl.Become(stateFunc);
- }
-
- template <typename T, typename... TArgs>
- void Become(T stateFunc, const TActorContext& ctx, TArgs&&... args) {
- CImpl.Become(stateFunc, ctx, std::forward<TArgs>(args)...);
- }
-
- template <typename T, typename... TArgs>
- void Become(T stateFunc, TArgs&&... args) {
- CImpl.Become(stateFunc);
- Schedule(std::forward<TArgs>(args)...);
- }
-
- TReceiveFunc CurrentStateFunc() const {
- return CImpl.CurrentStateFunc();
- }
- };
-
- template <typename TDerived>
- class TActor: public IActorCallback {
- private:
- using TDerivedReceiveFunc = void (TDerived::*)(TAutoPtr<IEventHandle>& ev);
-
- template <typename T, typename = const char*>
- struct HasActorName: std::false_type {};
- template <typename T>
- struct HasActorName<T, decltype((void)T::ActorName, (const char*)nullptr)>: std::true_type {};
-
- template <typename T, typename = const char*>
- struct HasActorActivityType: std::false_type {};
- template <typename T>
- struct HasActorActivityType<T, decltype((void)T::ActorActivityType, (const char*)nullptr)>: std::true_type {};
-
- static ui32 GetActivityTypeIndexImpl() {
- if constexpr(HasActorName<TDerived>::value) {
- return TLocalProcessKey<TActorActivityTag, TDerived::ActorName>::GetIndex();
- } else if constexpr (HasActorActivityType<TDerived>::value) {
- using TActorActivity = decltype(((TDerived*)nullptr)->ActorActivityType());
- static_assert(std::is_enum<TActorActivity>::value);
- return TEnumProcessKey<TActorActivityTag, TActorActivity>::GetIndex(TDerived::ActorActivityType());
- } else {
- // 200 characters is limit for solomon metric tag length
- return TLocalProcessExtKey<TActorActivityTag, TDerived, 200>::GetIndex();
- }
- }
-
- static ui32 GetActivityTypeIndex() {
- static const ui32 result = GetActivityTypeIndexImpl();
- return result;
- }
-
- protected:
- // static constexpr char ActorName[] = "UNNAMED";
-
- TActor(TDerivedReceiveFunc func)
- : IActorCallback(static_cast<TReceiveFunc>(func), GetActivityTypeIndex()) {
- }
-
- template <class TEnum = EActivityType>
- TActor(TDerivedReceiveFunc func, const TEnum activityEnumType = EActivityType::OTHER)
- : IActorCallback(static_cast<TReceiveFunc>(func), activityEnumType) {
- }
-
- TActor(TDerivedReceiveFunc func, const TString& actorName)
- : IActorCallback(static_cast<TReceiveFunc>(func), TLocalProcessKeyState<TActorActivityTag>::GetInstance().Register(actorName)) {
- }
-
- public:
- typedef TDerived TThis;
-
- // UnsafeBecome methods don't verify the bindings of the stateFunc to the TDerived
- template <typename T>
- void UnsafeBecome(T stateFunc) {
- this->IActorCallback::Become(stateFunc);
- }
-
- template <typename T, typename... TArgs>
- void UnsafeBecome(T stateFunc, const TActorContext& ctx, TArgs&&... args) {
- this->IActorCallback::Become(stateFunc, ctx, std::forward<TArgs>(args)...);
- }
-
- template <typename T, typename... TArgs>
- void UnsafeBecome(T stateFunc, TArgs&&... args) {
- this->IActorCallback::Become(stateFunc, std::forward<TArgs>(args)...);
- }
-
- template <typename T>
- void Become(T stateFunc) {
- // TODO(kruall): have to uncomment asserts after end of sync contrib/ydb
- // static_assert(std::is_convertible_v<T, TDerivedReceiveFunc>);
- this->IActorCallback::Become(stateFunc);
- }
-
- template <typename T, typename... TArgs>
- void Become(T stateFunc, const TActorContext& ctx, TArgs&&... args) {
- // static_assert(std::is_convertible_v<T, TDerivedReceiveFunc>);
- this->IActorCallback::Become(stateFunc, ctx, std::forward<TArgs>(args)...);
- }
-
- template <typename T, typename... TArgs>
- void Become(T stateFunc, TArgs&&... args) {
- // static_assert(std::is_convertible_v<T, TDerivedReceiveFunc>);
- this->IActorCallback::Become(stateFunc, std::forward<TArgs>(args)...);
- }
- };
-
-
-#define STFUNC_SIG TAutoPtr<::NActors::IEventHandle>& ev
-#define STATEFN_SIG TAutoPtr<::NActors::IEventHandle>& ev
-#define STFUNC(funcName) void funcName(TAutoPtr<::NActors::IEventHandle>& ev)
-#define STATEFN(funcName) void funcName(TAutoPtr<::NActors::IEventHandle>& ev)
-
-#define STFUNC_STRICT_UNHANDLED_MSG_HANDLER Y_DEBUG_ABORT_UNLESS(false, "%s: unexpected message type 0x%08" PRIx32, __func__, etype);
-
-#define STFUNC_BODY(HANDLERS, UNHANDLED_MSG_HANDLER) \
- switch (const ui32 etype = ev->GetTypeRewrite()) { \
- HANDLERS \
- default: \
- UNHANDLED_MSG_HANDLER \
- }
-
-#define STRICT_STFUNC_BODY(HANDLERS) STFUNC_BODY(HANDLERS, STFUNC_STRICT_UNHANDLED_MSG_HANDLER)
-
-#define STRICT_STFUNC(NAME, HANDLERS) \
- void NAME(STFUNC_SIG) { \
- STRICT_STFUNC_BODY(HANDLERS) \
- }
-
-#define STRICT_STFUNC_EXC(NAME, HANDLERS, EXCEPTION_HANDLERS) \
- void NAME(STFUNC_SIG) { \
- try { \
- STRICT_STFUNC_BODY(HANDLERS) \
- } \
- EXCEPTION_HANDLERS \
- }
-
- inline const TActorContext& TActivationContext::AsActorContext() {
- TActivationContext* tls = TlsActivationContext;
- return *static_cast<TActorContext*>(tls);
- }
-
- inline TActorContext TActivationContext::ActorContextFor(TActorId id) {
- auto& tls = *TlsActivationContext;
- return TActorContext(tls.Mailbox, tls.ExecutorThread, tls.EventStart, id);
- }
-
- class TDecorator : public IActorCallback {
- protected:
- THolder<IActor> Actor;
-
- public:
- TDecorator(THolder<IActor>&& actor)
- : IActorCallback(static_cast<TReceiveFunc>(&TDecorator::State), actor->GetActivityType())
- , Actor(std::move(actor))
- {
- }
-
- void Registered(TActorSystem* sys, const TActorId& owner) override {
- Actor->ChangeSelfId(SelfId());
- Actor->Registered(sys, owner);
- }
-
- virtual bool DoBeforeReceiving(TAutoPtr<IEventHandle>& /*ev*/, const TActorContext& /*ctx*/) {
- return true;
- }
-
- virtual void DoAfterReceiving(const TActorContext& /*ctx*/)
- {
- }
-
- STFUNC(State) {
- auto ctx(ActorContext());
- if (DoBeforeReceiving(ev, ctx)) {
- Actor->Receive(ev);
- DoAfterReceiving(ctx);
- }
- }
- };
-
- // TTestDecorator doesn't work with the real actor system
- struct TTestDecorator : public TDecorator {
- TTestDecorator(THolder<IActor>&& actor)
- : TDecorator(std::move(actor))
- {
- }
-
- virtual ~TTestDecorator() = default;
-
- // This method must be called in the test actor system
- bool BeforeSending(TAutoPtr<IEventHandle>& ev)
- {
- bool send = true;
- TTestDecorator *decorator = dynamic_cast<TTestDecorator*>(Actor.Get());
- if (decorator) {
- send = decorator->BeforeSending(ev);
- }
- return send && ev && DoBeforeSending(ev);
- }
-
- virtual bool DoBeforeSending(TAutoPtr<IEventHandle>& /*ev*/) {
- return true;
- }
- };
-
-
- template <ESendingType SendingType>
- bool TExecutorThread::Send(TAutoPtr<IEventHandle> ev) {
-#ifdef USE_ACTOR_CALLSTACK
- do {
- (ev)->Callstack = TCallstack::GetTlsCallstack();
- (ev)->Callstack.Trace();
- } while (false)
-#endif
- Ctx.IncrementSentEvents();
- return ActorSystem->Send<SendingType>(ev);
- }
-
- template <ESendingType SendingType>
- TActorId TExecutorThread::RegisterActor(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId,
- TActorId parentId)
- {
- if (!parentId) {
- parentId = CurrentRecipient;
- }
- if (poolId == Max<ui32>()) {
- if constexpr (SendingType == ESendingType::Common) {
- return Ctx.Executor->Register(actor, mailboxType, ++RevolvingWriteCounter, parentId);
- } else if (!TlsThreadContext) {
- return Ctx.Executor->Register(actor, mailboxType, ++RevolvingWriteCounter, parentId);
- } else {
- ESendingType previousType = std::exchange(TlsThreadContext->SendingType, SendingType);
- TActorId id = Ctx.Executor->Register(actor, mailboxType, ++RevolvingWriteCounter, parentId);
- TlsThreadContext->SendingType = previousType;
- return id;
- }
- } else {
- return ActorSystem->Register<SendingType>(actor, mailboxType, poolId, ++RevolvingWriteCounter, parentId);
- }
- }
-
- template <ESendingType SendingType>
- TActorId TExecutorThread::RegisterActor(IActor* actor, TMailboxHeader* mailbox, ui32 hint, TActorId parentId) {
- if (!parentId) {
- parentId = CurrentRecipient;
- }
- if constexpr (SendingType == ESendingType::Common) {
- return Ctx.Executor->Register(actor, mailbox, hint, parentId);
- } else if (!TlsActivationContext) {
- return Ctx.Executor->Register(actor, mailbox, hint, parentId);
- } else {
- ESendingType previousType = std::exchange(TlsThreadContext->SendingType, SendingType);
- TActorId id = Ctx.Executor->Register(actor, mailbox, hint, parentId);
- TlsThreadContext->SendingType = previousType;
- return id;
- }
- }
-
-
- template <ESendingType SendingType>
- bool TActivationContext::Send(TAutoPtr<IEventHandle> ev) {
- return TlsActivationContext->ExecutorThread.Send<SendingType>(ev);
- }
-
- template <ESendingType SendingType>
- bool TActivationContext::Send(std::unique_ptr<IEventHandle> &&ev) {
- return TlsActivationContext->ExecutorThread.Send<SendingType>(ev.release());
- }
-
- template <ESendingType SendingType>
- bool TActivationContext::Forward(TAutoPtr<IEventHandle>& ev, const TActorId& recipient) {
- return Send(IEventHandle::Forward(ev, recipient));
- }
-
- template <ESendingType SendingType>
- bool TActivationContext::Forward(THolder<IEventHandle>& ev, const TActorId& recipient) {
- return Send(IEventHandle::Forward(ev, recipient));
- }
-
- template <ESendingType SendingType>
- bool TActorContext::Send(const TActorId& recipient, IEventBase* ev, TEventFlags flags, ui64 cookie, NWilson::TTraceId traceId) const {
- return Send<SendingType>(new IEventHandle(recipient, SelfID, ev, flags, cookie, nullptr, std::move(traceId)));
- }
-
- template <ESendingType SendingType>
- bool TActorContext::Send(TAutoPtr<IEventHandle> ev) const {
- return ExecutorThread.Send<SendingType>(ev);
- }
-
- template <ESendingType SendingType>
- bool TActorContext::Forward(TAutoPtr<IEventHandle>& ev, const TActorId& recipient) const {
- return ExecutorThread.Send<SendingType>(IEventHandle::Forward(ev, recipient));
- }
-
- template <ESendingType SendingType>
- bool TActorContext::Forward(THolder<IEventHandle>& ev, const TActorId& recipient) const {
- return ExecutorThread.Send<SendingType>(IEventHandle::Forward(ev, recipient));
- }
-
- template <ESendingType SendingType>
- TActorId TActivationContext::Register(IActor* actor, TActorId parentId, TMailboxType::EType mailboxType, ui32 poolId) {
- return TlsActivationContext->ExecutorThread.RegisterActor<SendingType>(actor, mailboxType, poolId, parentId);
- }
-
- template <ESendingType SendingType>
- TActorId TActorContext::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) const {
- return ExecutorThread.RegisterActor<SendingType>(actor, mailboxType, poolId, SelfID);
- }
-
- template <ESendingType SendingType>
- bool TActorIdentity::Send(const TActorId& recipient, IEventBase* ev, TEventFlags flags, ui64 cookie, NWilson::TTraceId traceId) const {
- return TActivationContext::Send<SendingType>(new IEventHandle(recipient, *this, ev, flags, cookie, nullptr, std::move(traceId)));
- }
-
- template <ESendingType SendingType>
- bool IActor::Send(const TActorId& recipient, IEventBase* ev, TEventFlags flags, ui64 cookie, NWilson::TTraceId traceId) const {
- return SelfActorId.Send<SendingType>(recipient, ev, flags, cookie, std::move(traceId));
- }
-
- template <ESendingType SendingType>
- TActorId IActor::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) const noexcept {
- Y_ABORT_UNLESS(actor);
- return TlsActivationContext->ExecutorThread.RegisterActor<SendingType>(actor, mailboxType, poolId, SelfActorId);
- }
-
-
- template <ESendingType SendingType>
- TActorId TActorSystem::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 executorPool,
- ui64 revolvingCounter, const TActorId& parentId) {
- Y_ABORT_UNLESS(actor);
- Y_ABORT_UNLESS(executorPool < ExecutorPoolCount, "executorPool# %" PRIu32 ", ExecutorPoolCount# %" PRIu32,
- (ui32)executorPool, (ui32)ExecutorPoolCount);
- if constexpr (SendingType == ESendingType::Common) {
- return CpuManager->GetExecutorPool(executorPool)->Register(actor, mailboxType, revolvingCounter, parentId);
- } else if (!TlsThreadContext) {
- return CpuManager->GetExecutorPool(executorPool)->Register(actor, mailboxType, revolvingCounter, parentId);
- } else {
- ESendingType previousType = std::exchange(TlsThreadContext->SendingType, SendingType);
- TActorId id = CpuManager->GetExecutorPool(executorPool)->Register(actor, mailboxType, revolvingCounter, parentId);
- TlsThreadContext->SendingType = previousType;
- return id;
- }
- }
-
- template <ESendingType SendingType>
- bool TActorSystem::Send(TAutoPtr<IEventHandle> ev) const {
- if constexpr (SendingType == ESendingType::Common) {
- return this->GenericSend< &IExecutorPool::Send>(ev);
- } else {
- return this->SpecificSend(ev, SendingType);
- }
- }
-
-}
-
-template <>
-inline void Out<NActors::TActorIdentity>(IOutputStream& o, const NActors::TActorIdentity& x) {
- return x.Out(o);
-}
-
-template <>
-struct THash<NActors::TActorIdentity> {
- inline ui64 operator()(const NActors::TActorIdentity& x) const {
- return x.Hash();
- }
-};
-
-template<> struct std::hash<NActors::TActorIdentity> : THash<NActors::TActorIdentity> {};
diff --git a/library/cpp/actors/core/actor_benchmark_helper.h b/library/cpp/actors/core/actor_benchmark_helper.h
deleted file mode 100644
index 7e9651eb35..0000000000
--- a/library/cpp/actors/core/actor_benchmark_helper.h
+++ /dev/null
@@ -1,763 +0,0 @@
-#include "actor.h"
-#include "events.h"
-#include "actorsystem.h"
-#include "executor_pool_basic.h"
-#include "scheduler_basic.h"
-#include "actor_bootstrapped.h"
-
-#include <library/cpp/actors/testlib/test_runtime.h>
-#include <library/cpp/actors/util/threadparkpad.h>
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/threading/chunk_queue/queue.h>
-
-#include <util/generic/algorithm.h>
-#include <library/cpp/deprecated/atomic/atomic.h>
-#include <util/system/rwlock.h>
-#include <util/system/hp_timer.h>
-#include <vector>
-
-namespace NActors::NTests {
-
-struct TTestEndDecorator : TDecorator {
- TThreadParkPad* Pad;
- TAtomic* ActorsAlive;
-
- TTestEndDecorator(THolder<IActor>&& actor, TThreadParkPad* pad, TAtomic* actorsAlive)
- : TDecorator(std::move(actor))
- , Pad(pad)
- , ActorsAlive(actorsAlive)
- {
- AtomicIncrement(*ActorsAlive);
- }
-
- ~TTestEndDecorator() {
- if (AtomicDecrement(*ActorsAlive) == 0) {
- Pad->Unpark();
- }
- }
-};
-
-
-struct TActorBenchmarkSettings {
- static constexpr bool DefaultNoRealtime = true;
- static constexpr ui32 DefaultSpinThreshold = 1'000'000;
- static constexpr ui32 TotalEventsAmountPerThread = 1'000;
-
- static constexpr auto MailboxTypes = {
- TMailboxType::Simple,
- TMailboxType::Revolving,
- TMailboxType::HTSwap,
- TMailboxType::ReadAsFilled,
- TMailboxType::TinyReadAsFilled
- };
-};
-
-
-template <typename TSettings_ = TActorBenchmarkSettings>
-struct TActorBenchmark {
- using TSettings = TSettings_;
-
- class TDummyActor : public TActor<TDummyActor> {
- public:
- TDummyActor() : TActor<TDummyActor>(&TDummyActor::StateFunc) {}
- STFUNC(StateFunc) {
- (void)ev;
- }
- };
-
- enum class ERole {
- Leader,
- Follower
- };
-
- struct TEvOwnedPing : TEvents::TEvPing {
- TEvOwnedPing(TActorId owner)
- : TEvPing()
- , Owner(owner)
- {}
-
- TActorId Owner;
- };
-
- struct TEventSharedCounters {
- TEventSharedCounters(ui32 count)
- : NotStarted(count)
- , Finished(0)
- , Counters(count)
- , StartedCounters(count)
- , EndedCounters(count)
- {
- for (ui32 idx = 0; idx < count; ++idx) {
- Counters[idx].store(0);
- StartedCounters[idx].store(0);
- EndedCounters[idx].store(0);
- }
- }
-
- std::atomic<ui64> NotStarted = 0;
- std::atomic<ui64> Finished = 0;
- std::vector<NThreading::TPadded<std::atomic<ui64>>> Counters;
- std::vector<NThreading::TPadded<std::atomic<ui64>>> StartedCounters;
- std::vector<NThreading::TPadded<std::atomic<ui64>>> EndedCounters;
- std::atomic<ui64> StartTimeTs = 0;
- std::atomic<ui64> EndTimeTs = 0;
- std::atomic<bool> DoStop = false;
- };
-
- struct TSendReceiveActorParams {
- ui64 OwnEvents = 0;
- ui64 OtherEvents = 0;
- bool EndlessSending = false;
- double *ElapsedTime = nullptr;
- std::vector<TActorId> Receivers;
- bool Allocation = false;
- ESendingType SendingType = ESendingType::Common;
- ui32 Neighbours = 0;
- TEventSharedCounters *SharedCounters;
- ui32 InFlight = 1;
- };
-
- class TSendReceiveActor : public TActorBootstrapped<TSendReceiveActor> {
- public:
- static constexpr auto ActorActivityType() {
- return IActorCallback::EActivityType::ACTORLIB_COMMON;
- }
-
- TSendReceiveActor(const TSendReceiveActorParams &params, ui32 idx=0)
- : OwnEventsCounter(params.OwnEvents)
- , OtherEventsCounter(params.OtherEvents)
- , ElapsedTime(params.ElapsedTime)
- , Receivers(params.Receivers)
- , AllocatesMemory(params.Allocation)
- , SendingType(params.SendingType)
- , MailboxNeighboursCount(params.Neighbours)
- , SharedCounters(params.SharedCounters)
- , PairIdx(idx)
- , EndlessSending(params.EndlessSending)
- , IsLeader(OwnEventsCounter)
- , InFlight(params.InFlight)
- {}
-
- void StoreCounters(std::vector<NThreading::TPadded<std::atomic<ui64>>> &dest) {
- for (ui32 idx = 0; idx < dest.size(); ++idx) {
- dest[idx].store(SharedCounters->Counters[idx]);
- }
- }
-
- void Bootstrap(const TActorContext &ctx) {
- if (SharedCounters && IsLeader) {
- ui32 count = --SharedCounters->NotStarted;
- if (!count) {
- SharedCounters->StartTimeTs = GetCycleCountFast();
- StoreCounters(SharedCounters->StartedCounters);
- }
- }
- if (Receivers.empty() && OwnEventsCounter) {
- Receivers.push_back(this->SelfId());
- }
- Timer.Reset();
- this->Become(&TSendReceiveActor::StateFunc);
- for (ui32 i = 0; i < MailboxNeighboursCount; ++i) {
- ctx.RegisterWithSameMailbox(new TDummyActor());
- }
- for (TActorId receiver : Receivers) {
- for (ui32 eventIdx = 0; eventIdx < InFlight; ++eventIdx) {
- TAutoPtr<IEventHandle> ev = new IEventHandle(receiver, this->SelfId(), new TEvOwnedPing(this->SelfId()));
- SpecialSend(ev, ctx, true);
- }
- }
- }
-
- void SpecialSend(TAutoPtr<IEventHandle> ev, const TActorContext &ctx, bool own) {
- EventsCounter++;
- if (own) {
- --OwnEventsCounter;
- }
- if (SendingType == ESendingType::Lazy) {
- ctx.Send<ESendingType::Lazy>(ev);
- } else if (SendingType == ESendingType::Tail) {
- ctx.Send<ESendingType::Tail>(ev);
- } else {
- ctx.Send(ev);
- }
- }
-
- void Stop() {
- if (SharedCounters && IsLeader) {
- if (!SharedCounters->NotStarted++) {
- StoreCounters(SharedCounters->EndedCounters);
- SharedCounters->EndTimeTs = GetCycleCountFast();
- }
- }
- if (ElapsedTime != nullptr) {
- if (Receivers.size() && Receivers[0] != this->SelfId()) {
- *ElapsedTime = Timer.Passed() / EventsCounter;
- } else {
- *ElapsedTime = Timer.Passed() * 2 / EventsCounter;
- }
- }
- this->PassAway();
- }
-
- bool CheckWorkIsDone() {
- if (OwnEventsCounter || OtherEventsCounter || EndlessSending) {
- return false;
- }
- Stop();
- return true;
- }
-
- STFUNC(StateFunc) {
- ++EventsCounter;
- ui32 counter = ++ReceiveTurn;
- if (SharedCounters) {
- if (counter % 128 == 0) {
- if (IsLeader) {
- SharedCounters->Counters[PairIdx].store(EventsCounter);
- }
- if (SharedCounters->DoStop) {
- Stop();
- return;
- }
- }
- }
- bool own = ev->Get<TEvOwnedPing>()->Owner == this->SelfId();
- if (!own) {
- --OtherEventsCounter;
- }
- if (CheckWorkIsDone())
- return;
-
- auto ctx(this->ActorContext());
- if (AllocatesMemory) {
- SpecialSend(new IEventHandle(ev->Sender, this->SelfId(), new TEvOwnedPing(ev->Get<TEvOwnedPing>()->Owner)), ctx, own);
- } else {
- std::swap(*const_cast<TActorId*>(&ev->Sender), *const_cast<TActorId*>(&ev->Recipient));
- ev->DropRewrite();
- SpecialSend(ev, ctx, own);
- }
-
- CheckWorkIsDone();
- }
-
- private:
- THPTimer Timer;
- ui64 OwnEventsCounter;
- ui64 OtherEventsCounter;
- double* ElapsedTime;
- std::vector<TActorId> Receivers;
- bool AllocatesMemory;
- ESendingType SendingType;
- ui32 MailboxNeighboursCount;
- ui32 EventsCounter = 0;
- TEventSharedCounters *SharedCounters;
- ui32 PairIdx = 0;
- bool EndlessSending = false;
- bool IsLeader = false;
- ui32 InFlight = 1;
- ui32 ReceiveTurn = 0;
- };
-
- static void AddBasicPool(THolder<TActorSystemSetup>& setup, ui32 threads, bool activateEveryEvent, i16 sharedExecutorsCount) {
- TBasicExecutorPoolConfig basic;
- basic.PoolId = setup->GetExecutorsCount();
- basic.PoolName = TStringBuilder() << "b" << basic.PoolId;
- basic.Threads = threads;
- basic.SpinThreshold = TSettings::DefaultSpinThreshold;
- basic.TimePerMailbox = TDuration::Hours(1);
- basic.SharedExecutorsCount = sharedExecutorsCount;
- basic.SoftProcessingDurationTs = Us2Ts(100);
- if (activateEveryEvent) {
- basic.EventsPerMailbox = 1;
- }
- setup->CpuManager.Basic.emplace_back(std::move(basic));
- }
-
- static void AddUnitedPool(THolder<TActorSystemSetup>& setup, ui32 concurrency, bool activateEveryEvent) {
- TUnitedExecutorPoolConfig united;
- united.PoolId = setup->GetExecutorsCount();
- united.PoolName = TStringBuilder() << "u" << united.PoolId;
- united.Concurrency = concurrency;
- united.TimePerMailbox = TDuration::Hours(1);
- if (activateEveryEvent) {
- united.EventsPerMailbox = 1;
- } else {
- united.EventsPerMailbox = ::Max<ui32>();
- }
- setup->CpuManager.United.emplace_back(std::move(united));
- }
-
- static THolder<TActorSystemSetup> GetActorSystemSetup(ui32 unitedCpuCount, bool preemption) {
- auto setup = MakeHolder<NActors::TActorSystemSetup>();
- setup->NodeId = 1;
- setup->CpuManager.UnitedWorkers.CpuCount = unitedCpuCount;
- setup->CpuManager.UnitedWorkers.SpinThresholdUs = TSettings::DefaultSpinThreshold;
- setup->CpuManager.UnitedWorkers.NoRealtime = TSettings::DefaultNoRealtime;
- if (preemption) {
- setup->CpuManager.UnitedWorkers.PoolLimitUs = 500;
- setup->CpuManager.UnitedWorkers.EventLimitUs = 100;
- setup->CpuManager.UnitedWorkers.LimitPrecisionUs = 100;
- } else {
- setup->CpuManager.UnitedWorkers.PoolLimitUs = 100'000'000'000;
- setup->CpuManager.UnitedWorkers.EventLimitUs = 10'000'000'000;
- setup->CpuManager.UnitedWorkers.LimitPrecisionUs = 10'000'000'000;
- }
- setup->Scheduler = new TBasicSchedulerThread(NActors::TSchedulerConfig(512, 0));
- return setup;
- }
-
- enum class EPoolType {
- Basic,
- United
- };
-
- static THolder<TActorSystemSetup> InitActorSystemSetup(EPoolType poolType, ui32 poolsCount, ui32 threads, bool activateEveryEvent, bool preemption) {
- if (poolType == EPoolType::Basic) {
- THolder<TActorSystemSetup> setup = GetActorSystemSetup(0, false);
- for (ui32 i = 0; i < poolsCount; ++i) {
- AddBasicPool(setup, threads, activateEveryEvent, 0);
- }
- return setup;
- } else if (poolType == EPoolType::United) {
- THolder<TActorSystemSetup> setup = GetActorSystemSetup(poolsCount * threads, preemption);
- for (ui32 i = 0; i < poolsCount; ++i) {
- AddUnitedPool(setup, threads, activateEveryEvent);
- }
- return setup;
- }
- Y_ABORT();
- }
-
- static double BenchSendReceive(bool allocation, NActors::TMailboxType::EType mType, EPoolType poolType, ESendingType sendingType) {
- THolder<TActorSystemSetup> setup = InitActorSystemSetup(poolType, 1, 1, false, false);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- TThreadParkPad pad;
- TAtomic actorsAlive = 0;
- double elapsedTime = 0;
- THolder<IActor> endActor{new TTestEndDecorator(
- THolder(new TSendReceiveActor(
- TSendReceiveActorParams{
- .OwnEvents=TSettings::TotalEventsAmountPerThread,
- .OtherEvents=0,
- .ElapsedTime=&elapsedTime,
- .Allocation=allocation,
- .SendingType=sendingType,
- }
- )),
- &pad,
- &actorsAlive
- )};
-
- actorSystem.Register(endActor.Release(), mType);
-
- pad.Park();
- actorSystem.Stop();
-
- return 1e9 * elapsedTime;
- }
-
- static double BenchSendActivateReceive(ui32 poolsCount, ui32 threads, bool allocation, EPoolType poolType, ESendingType sendingType) {
- THolder<TActorSystemSetup> setup = InitActorSystemSetup(poolType, poolsCount, threads, true, false);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- TThreadParkPad pad;
- TAtomic actorsAlive = 0;
- double elapsedTime = 0;
- ui32 followerPoolId = 0;
-
- ui32 leaderPoolId = poolsCount == 1 ? 0 : 1;
- ui64 eventsPerPair = TSettings::TotalEventsAmountPerThread;
-
- TActorId followerId = actorSystem.Register(
- new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{.OtherEvents=eventsPerPair / 2, .Allocation=allocation}
- ),
- TMailboxType::HTSwap,
- followerPoolId
- );
- THolder<IActor> leader{
- new TTestEndDecorator(
- THolder(new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{
- .OwnEvents=eventsPerPair / 2,
- .ElapsedTime=&elapsedTime,
- .Receivers={followerId},
- .Allocation=allocation,
- .SendingType=sendingType,
- }
- )),
- &pad,
- &actorsAlive
- )
- };
- actorSystem.Register(leader.Release(), TMailboxType::HTSwap, leaderPoolId);
-
- pad.Park();
- actorSystem.Stop();
-
- return 1e9 * elapsedTime;
- }
-
- static double BenchSendActivateReceiveWithMailboxNeighbours(ui32 MailboxNeighbourActors, EPoolType poolType, ESendingType sendingType) {
- THolder<TActorSystemSetup> setup = InitActorSystemSetup(poolType, 1, 1, false, false);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- TThreadParkPad pad;
- TAtomic actorsAlive = 0;
- double elapsedTime = 0;
-
- ui64 eventsPerPair = TSettings::TotalEventsAmountPerThread;
-
- TActorId followerId = actorSystem.Register(
- new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{
- .OtherEvents=eventsPerPair / 2,
- .Allocation=false,
- .Neighbours=MailboxNeighbourActors,
- }
- ),
- TMailboxType::HTSwap
- );
- THolder<IActor> leader{
- new TTestEndDecorator(
- THolder(new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{
- .OwnEvents=eventsPerPair / 2,
- .ElapsedTime=&elapsedTime,
- .Receivers={followerId},
- .Allocation=false,
- .SendingType=sendingType,
- .Neighbours=MailboxNeighbourActors,
- }
- )),
- &pad,
- &actorsAlive
- )
- };
- actorSystem.Register(leader.Release(), TMailboxType::HTSwap);
-
- pad.Park();
- actorSystem.Stop();
-
- return 1e9 * elapsedTime;
- }
-
- struct TBenchResult {
- double ElapsedTime;
- ui64 SentEvents;
- ui64 MinPairSentEvents;
- ui64 MaxPairSentEvents;
- };
-
- static auto BenchContentedThreads(ui32 threads, ui32 actorsPairsCount, EPoolType poolType, ESendingType sendingType, TDuration testDuration = TDuration::Zero(), ui32 inFlight = 1) {
- THolder<TActorSystemSetup> setup = InitActorSystemSetup(poolType, 1, threads, false, false);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- TThreadParkPad pad;
- TAtomic actorsAlive = 0;
-
- TEventSharedCounters sharedCounters(actorsPairsCount);
-
- ui64 totalEvents = TSettings::TotalEventsAmountPerThread * threads;
- ui64 eventsPerPair = totalEvents / actorsPairsCount;
-
- for (ui32 i = 0; i < actorsPairsCount; ++i) {
- ui32 followerPoolId = 0;
- ui32 leaderPoolId = 0;
- TActorId followerId = actorSystem.Register(
- new TSendReceiveActor(
- TSendReceiveActorParams{
- .OtherEvents = eventsPerPair / 2,
- .EndlessSending = bool(testDuration),
- .Allocation = false,
- .SharedCounters = &sharedCounters,
- }
- ),
- TMailboxType::HTSwap,
- followerPoolId
- );
- THolder<IActor> leader{
- new TTestEndDecorator(
- THolder(new TSendReceiveActor(TSendReceiveActorParams{
- .OwnEvents = eventsPerPair / 2,
- .EndlessSending = bool(testDuration),
- .Receivers={followerId},
- .Allocation = false,
- .SendingType=sendingType,
- .SharedCounters=&sharedCounters,
- .InFlight = inFlight
- }, i)),
- &pad,
- &actorsAlive
- )
- };
- actorSystem.Register(leader.Release(), TMailboxType::HTSwap, leaderPoolId);
- }
-
- if (testDuration) {
- Sleep(testDuration);
- for (ui32 idx = 0; idx < actorsPairsCount; ++idx) {
- sharedCounters.EndedCounters[idx].store(sharedCounters.Counters[idx]);
- }
- sharedCounters.EndTimeTs = GetCycleCountFast();
- } else {
- pad.Park();
- }
- actorSystem.Stop();
-
- ui64 sentEvents = sharedCounters.EndedCounters[0] - sharedCounters.StartedCounters[0];
- ui64 minSentEvents = sentEvents;
- ui64 maxSentEvents = sentEvents;
- for (ui32 pairIdx = 1; pairIdx < actorsPairsCount; ++pairIdx) {
- ui64 count = sharedCounters.EndedCounters[pairIdx] - sharedCounters.StartedCounters[pairIdx];
- sentEvents += count;
- minSentEvents = ::Min(minSentEvents, count);
- maxSentEvents = ::Max(maxSentEvents, count);
- }
-
- return TBenchResult {
- .ElapsedTime = 1000 * Ts2Us(sharedCounters.EndTimeTs - sharedCounters.StartTimeTs),
- .SentEvents = sentEvents,
- .MinPairSentEvents = minSentEvents,
- .MaxPairSentEvents = maxSentEvents
- };
- }
-
- static auto BenchStarContentedThreads(ui32 threads, ui32 actorsPairsCount, EPoolType poolType, ESendingType sendingType, TDuration testDuration = TDuration::Zero(), ui32 starMultiply=10) {
- THolder<TActorSystemSetup> setup = InitActorSystemSetup(poolType, 1, threads, true, false);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- TThreadParkPad pad;
- TAtomic actorsAlive = 0;
-
- TEventSharedCounters sharedCounters(actorsPairsCount);
-
- ui64 totalEvents = TSettings::TotalEventsAmountPerThread * threads;
- ui64 eventsPerPair = totalEvents / actorsPairsCount;
-
- for (ui32 i = 0; i < actorsPairsCount; ++i) {
- ui32 followerPoolId = 0;
- ui32 leaderPoolId = 0;
- std::vector<TActorId> receivers;
- for (ui32 idx = 0; idx < starMultiply; ++idx) {
- TActorId followerId = actorSystem.Register(
- new TSendReceiveActor(
- TSendReceiveActorParams{
- .OtherEvents = eventsPerPair / 2 / starMultiply,
- .EndlessSending = bool(testDuration),
- .Allocation = false,
- .SharedCounters = &sharedCounters,
- }
- ),
- TMailboxType::HTSwap,
- followerPoolId
- );
- receivers.push_back(followerId);
- }
- THolder<IActor> leader{
- new TTestEndDecorator(
- THolder(new TSendReceiveActor(TSendReceiveActorParams{
- .OwnEvents = eventsPerPair / 2,
- .EndlessSending = bool(testDuration),
- .Receivers=receivers,
- .Allocation = false,
- .SendingType=sendingType,
- .SharedCounters=&sharedCounters,
- }, i)),
- &pad,
- &actorsAlive
- )
- };
- actorSystem.Register(leader.Release(), TMailboxType::HTSwap, leaderPoolId);
- }
-
- if (testDuration) {
- Sleep(testDuration);
- for (ui32 idx = 0; idx < actorsPairsCount; ++idx) {
- sharedCounters.EndedCounters[idx].store(sharedCounters.Counters[idx]);
- }
- sharedCounters.EndTimeTs = GetCycleCountFast();
- } else {
- pad.Park();
- }
- actorSystem.Stop();
-
- ui64 sentEvents = sharedCounters.EndedCounters[0] - sharedCounters.StartedCounters[0];
- ui64 minSentEvents = sentEvents;
- ui64 maxSentEvents = sentEvents;
- for (ui32 pairIdx = 1; pairIdx < actorsPairsCount; ++pairIdx) {
- ui64 count = sharedCounters.EndedCounters[pairIdx] - sharedCounters.StartedCounters[pairIdx];
- sentEvents += count;
- minSentEvents = ::Min(minSentEvents, count);
- maxSentEvents = ::Max(maxSentEvents, count);
- }
-
- return TBenchResult {
- .ElapsedTime = 1000 * Ts2Us(sharedCounters.EndTimeTs - sharedCounters.StartTimeTs),
- .SentEvents = sentEvents,
- .MinPairSentEvents = minSentEvents,
- .MaxPairSentEvents = maxSentEvents
- };
- }
-
-
- static auto Mean(const std::vector<double>& data) {
- return Accumulate(data.begin(), data.end(), 0.0) / data.size();
- }
-
- static auto Deviation(const std::vector<double>& data) {
- auto mean = Mean(data);
- double deviation = 0.0;
- for (const auto& x : data) {
- deviation += (x - mean) * (x - mean);
- }
- return std::sqrt(deviation / data.size());
- }
-
- static double Min(const std::vector<double>& data) {
- return *std::min_element(data.begin(), data.end());
- }
-
- static double Max(const std::vector<double>& data) {
- return *std::max_element(data.begin(), data.end());
- }
-
- template <auto Measurment>
- struct TStats {
- double Mean;
- double Deviation;
- double Min;
- double Max;
-
- TStats(const std::vector<double> &data)
- : Mean(TActorBenchmark::Mean(data))
- , Deviation(TActorBenchmark::Deviation(data))
- , Min(TActorBenchmark::Min(data))
- , Max(TActorBenchmark::Max(data))
- {
- }
-
- TString ToString() {
- return TStringBuilder() << Mean << " ± " << Deviation << " " << Measurment()
- << " " << std::ceil(Deviation / Mean * 1000) / 10.0 << "%"
- << " min " << Min << " " << Measurment() << " max " << Max << " " << Measurment();
- }
- };
-
- static constexpr auto EmptyMsr = []{return "";};
- static constexpr auto NsMsr = []{return "ns";};
-
- struct TStatsBenchResult {
- TStats<NsMsr> ElapsedTime;
- TStats<EmptyMsr> SentEvents;
- TStats<EmptyMsr> MinPairSentEvents;
- TStats<EmptyMsr> MaxPairSentEvents;
-
- TString ToString() {
- return TStringBuilder() << ElapsedTime.ToString() << Endl << SentEvents.ToString() << Endl << MinPairSentEvents.ToString() << Endl << MaxPairSentEvents.ToString();
- }
- };
-
- template <typename Func>
- static auto CountStats(Func func, ui32 itersCount = 5) {
- if constexpr (std::is_same_v<double, std::decay_t<decltype(func())>>) {
- std::vector<double> elapsedTimes;
- for (ui32 i = 0; i < itersCount; ++i) {
- auto elapsedTime = func();
- elapsedTimes.push_back(elapsedTime);
- }
- return TStats<NsMsr>(elapsedTimes);
- } else {
- std::vector<double> elapsedTimes;
- std::vector<double> sentEvents;
- std::vector<double> minPairSentEvents;
- std::vector<double> maxPairSentEvents;
- for (ui32 i = 0; i < itersCount; ++i) {
- TBenchResult result = func();
- elapsedTimes.push_back(result.ElapsedTime);
- sentEvents.push_back(result.SentEvents);
- minPairSentEvents.push_back(result.MinPairSentEvents);
- maxPairSentEvents.push_back(result.MaxPairSentEvents);
- }
- return TStatsBenchResult {
- .ElapsedTime = TStats<NsMsr>(elapsedTimes),
- .SentEvents = TStats<EmptyMsr>(sentEvents),
- .MinPairSentEvents = TStats<EmptyMsr>(minPairSentEvents),
- .MaxPairSentEvents = TStats<EmptyMsr>(maxPairSentEvents),
- };
- }
- }
-
- static void RunBenchSendActivateReceive(ui32 poolsCount, ui32 threads, bool allocation, EPoolType poolType) {
- auto stats = CountStats([=] {
- return BenchSendActivateReceive(poolsCount, threads, allocation, poolType, ESendingType::Common);
- });
- Cerr << stats.ToString() << Endl;
- stats = CountStats([=] {
- return BenchSendActivateReceive(poolsCount, threads, allocation, poolType, ESendingType::Lazy);
- });
- Cerr << stats.ToString() << " Lazy" << Endl;
- stats = CountStats([=] {
- return BenchSendActivateReceive(poolsCount, threads, allocation, poolType, ESendingType::Tail);
- });
- Cerr << stats.ToString() << " Tail" << Endl;
- }
-
- static void RunBenchContentedThreads(ui32 threads, EPoolType poolType) {
- for (ui32 actorPairs = 1; actorPairs <= 2 * threads; actorPairs++) {
- auto stats = CountStats([threads, actorPairs, poolType] {
- return BenchContentedThreads(threads, actorPairs, poolType, ESendingType::Common);
- });
- Cerr << stats.ToString() << " actorPairs: " << actorPairs << Endl;
- stats = CountStats([threads, actorPairs, poolType] {
- return BenchContentedThreads(threads, actorPairs, poolType, ESendingType::Lazy);
- });
- Cerr << stats.ToString() << " actorPairs: " << actorPairs << " Lazy"<< Endl;
- stats = CountStats([threads, actorPairs, poolType] {
- return BenchContentedThreads(threads, actorPairs, poolType, ESendingType::Tail);
- });
- Cerr << stats.ToString() << " actorPairs: " << actorPairs << " Tail"<< Endl;
- }
- }
-
- static void RunSendActivateReceiveCSV(const std::vector<ui32> &threadsList, const std::vector<ui32> &actorPairsList, const std::vector<ui32> &inFlights, TDuration subtestDuration) {
- Cout << "threads,actorPairs,in_flight,msgs_per_sec,elapsed_seconds,min_pair_sent_msgs,max_pair_sent_msgs" << Endl;
- for (ui32 threads : threadsList) {
- for (ui32 actorPairs : actorPairsList) {
- for (ui32 inFlight : inFlights) {
- auto stats = CountStats([threads, actorPairs, inFlight, subtestDuration] {
- return BenchContentedThreads(threads, actorPairs, EPoolType::Basic, ESendingType::Common, subtestDuration, inFlight);
- }, 3);
- double elapsedSeconds = stats.ElapsedTime.Mean / 1e9;
- ui64 eventsPerSecond = stats.SentEvents.Mean / elapsedSeconds;
- Cout << threads << "," << actorPairs << "," << inFlight << "," << eventsPerSecond << "," << elapsedSeconds << "," << stats.MinPairSentEvents.Min << "," << stats.MaxPairSentEvents.Max << Endl;
- }
- }
- }
- }
-
-
- static void RunStarSendActivateReceiveCSV(const std::vector<ui32> &threadsList, const std::vector<ui32> &actorPairsList, const std::vector<ui32> &starsList) {
- Cout << "threads,actorPairs,star_multiply,msgs_per_sec,elapsed_seconds,min_pair_sent_msgs,max_pair_sent_msgs" << Endl;
- for (ui32 threads : threadsList) {
- for (ui32 actorPairs : actorPairsList) {
- for (ui32 stars : starsList) {
- auto stats = CountStats([threads, actorPairs, stars] {
- return BenchStarContentedThreads(threads, actorPairs, EPoolType::Basic, ESendingType::Common, TDuration::Seconds(1), stars);
- }, 3);
- double elapsedSeconds = stats.ElapsedTime.Mean / 1e9;
- ui64 eventsPerSecond = stats.SentEvents.Mean / elapsedSeconds;
- Cout << threads << "," << actorPairs << "," << stars << "," << eventsPerSecond << "," << elapsedSeconds << "," << stats.MinPairSentEvents.Min << "," << stats.MaxPairSentEvents.Max << Endl;
- }
- }
- }
- }
-};
-
-} // NActors::NTests
diff --git a/library/cpp/actors/core/actor_bootstrapped.cpp b/library/cpp/actors/core/actor_bootstrapped.cpp
deleted file mode 100644
index 8c1effcd5d..0000000000
--- a/library/cpp/actors/core/actor_bootstrapped.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "actor_bootstrapped.h"
-
-namespace NActors {
-}
diff --git a/library/cpp/actors/core/actor_bootstrapped.h b/library/cpp/actors/core/actor_bootstrapped.h
deleted file mode 100644
index 70a6163bc5..0000000000
--- a/library/cpp/actors/core/actor_bootstrapped.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-
-#include "actorsystem.h"
-#include "actor.h"
-#include "events.h"
-#include <util/generic/noncopyable.h>
-
-namespace NActors {
- 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);
- }
-
- STFUNC(StateBootstrap) {
- Y_ABORT_UNLESS(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(TActivationContext::ActorContextFor(TActor<TDerived>::SelfId()));
- } else if constexpr (std::is_invocable_v<T, TDerived, const TActorId&, const TActorContext&>) {
- self.Bootstrap(ev->Sender, TActivationContext::ActorContextFor(TActor<TDerived>::SelfId()));
- } 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");
- }
- }
-
- TActorBootstrapped()
- : TActor<TDerived>(&TDerived::StateBootstrap) {
- }
-
- template <class TEnum>
- TActorBootstrapped(const TEnum activityType)
- : TActor<TDerived>(&TDerived::StateBootstrap, activityType) {
- }
-
- TActorBootstrapped(const TString& activityName)
- : TActor<TDerived>(&TDerived::StateBootstrap, activityName) {
- }
- };
-}
diff --git a/library/cpp/actors/core/actor_coroutine.cpp b/library/cpp/actors/core/actor_coroutine.cpp
deleted file mode 100644
index 32390eaae3..0000000000
--- a/library/cpp/actors/core/actor_coroutine.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-#include "actor_coroutine.h"
-#include "executor_thread.h"
-
-#include <util/system/sanitizers.h>
-#include <util/system/type_name.h>
-#include <util/system/info.h>
-#include <util/system/protect.h>
-
-namespace NActors {
- static const size_t PageSize = NSystemInfo::GetPageSize();
-
-#if !CORO_THROUGH_THREADS
- static size_t AlignStackSize(size_t size) {
- size += PageSize - (size & PageSize - 1) & PageSize - 1;
-#ifndef NDEBUG
- size += PageSize;
-#endif
- return size;
- }
-#endif
-
- TActorCoroImpl::TActorCoroImpl(size_t stackSize, bool allowUnhandledDtor)
- : AllowUnhandledDtor(allowUnhandledDtor)
-#if !CORO_THROUGH_THREADS
- , Stack(AlignStackSize(stackSize))
- , FiberClosure{this, TArrayRef(Stack.Begin(), Stack.End())}
- , FiberContext(FiberClosure)
-#endif
- {
- Y_UNUSED(stackSize);
-#if !CORO_THROUGH_THREADS && !defined(NDEBUG)
- ProtectMemory(STACK_GROW_DOWN ? Stack.Begin() : Stack.End() - PageSize, PageSize, EProtectMemoryMode::PM_NONE);
-#endif
- }
-
- void TActorCoroImpl::Destroy() {
- if (!Finished) { // only resume when we have bootstrapped and Run() was entered and not yet finished; in other case simply terminate
- InvokedFromDtor = true;
- Resume(nullptr);
- }
-#if CORO_THROUGH_THREADS
- if (WorkerThread.joinable()) {
- WorkerThread.join();
- }
-#endif
- }
-
- bool TActorCoroImpl::Send(TAutoPtr<IEventHandle> ev) {
- return GetActorContext().ExecutorThread.Send(ev);
- }
-
- THolder<IEventHandle> TActorCoroImpl::WaitForEvent(TMonotonic deadline) {
- IEventHandle *timeoutEv = nullptr;
- if (deadline != TMonotonic::Max()) {
- TActivationContext::Schedule(deadline, timeoutEv = new IEventHandle(TEvents::TSystem::CoroTimeout, 0,
- SelfActorId, {}, nullptr, 0));
- }
-
- // ensure we have no unprocessed event and return back to actor system to receive one
- Y_ABORT_UNLESS(!Finished);
-
- // obtain pending event and ensure we've got one
- while (THolder<IEventHandle> event = ReturnToActorSystem()) {
- if (event->GetTypeRewrite() != TEvents::TSystem::CoroTimeout) {
- return event;
- } else if (event.Get() == timeoutEv) {
- return nullptr; // it is not a race -- we've got timeout exactly for our current wait
- }
- }
- Y_ABORT("no pending event");
- }
-
- bool TActorCoroImpl::ProcessEvent(THolder<IEventHandle> ev) {
- if (!SelfActorId) { // process bootstrap message, extract actor ids
- Y_ABORT_UNLESS(ev->GetTypeRewrite() == TEvents::TSystem::Bootstrap);
- SelfActorId = ev->Recipient;
- ParentActorId = ev->Sender;
- ev.Reset();
-#if CORO_THROUGH_THREADS
- WorkerThread = std::thread(std::bind(&TActorCoroImpl::DoRun, this));
-#endif
- }
-
- // prepare actor context for in-coroutine use
- TActivationContext *ac = TlsActivationContext;
- TActorContext actorContext(ac->Mailbox, ac->ExecutorThread, ac->EventStart, SelfActorId);
- TlsActivationContext = &actorContext;
-
- Resume(std::move(ev));
-
- // drop actor context
- TlsActivationContext = ac;
-
- return Finished;
- }
-
- void TActorCoroImpl::Resume(THolder<IEventHandle> ev) {
- BeforeResume();
-
- Y_ABORT_UNLESS(!PendingEvent);
- PendingEvent.Swap(ev);
-
-#if CORO_THROUGH_THREADS
- ActivationContext = TlsActivationContext;
- InEvent.Signal();
- OutEvent.Wait();
-#else
- // save caller context for a later return
- Y_ABORT_UNLESS(!ActorSystemContext);
- TExceptionSafeContext actorSystemContext;
- ActorSystemContext = &actorSystemContext;
-
- // go to actor coroutine
- ActorSystemContext->SwitchTo(&FiberContext);
-#endif
-
- Y_ABORT_UNLESS(!PendingEvent);
- }
-
- void TActorCoroImpl::DoRun() {
-#if CORO_THROUGH_THREADS
- InEvent.Wait();
- TlsActivationContext = ActivationContext;
-#endif
- if (!InvokedFromDtor) {
- try {
- Run();
- } catch (const TDtorException& /*ex*/) {
- if (!AllowUnhandledDtor) {
- Y_ABORT("unhandled TDtorException");
- }
- } catch (const std::exception& ex) {
- Y_ABORT("unhandled exception of type %s", TypeName(ex).data());
- } catch (...) {
- Y_ABORT("unhandled exception of type not derived from std::exception");
- }
- }
- Finished = true;
- ReturnToActorSystem();
- }
-
- THolder<IEventHandle> TActorCoroImpl::ReturnToActorSystem() {
-#if CORO_THROUGH_THREADS
- OutEvent.Signal();
- if (Finished) {
- return nullptr;
- } else {
- InEvent.Wait(); // wait for reentry
- TlsActivationContext = ActivationContext;
- }
-#else
- TExceptionSafeContext* returnContext = std::exchange(ActorSystemContext, nullptr);
- Y_ABORT_UNLESS(returnContext);
- if (StoreTlsState) {
- StoreTlsState(this);
- }
- FiberContext.SwitchTo(returnContext);
- if (RestoreTlsState) {
- RestoreTlsState(this);
- }
-#endif
-
- if (THolder<IEventHandle> ev = std::exchange(PendingEvent, nullptr)) {
- return ev;
- } else {
- // we have returned from the actor system and it kindly asks us to terminate the coroutine as it is being
- // stopped
- Y_ABORT_UNLESS(InvokedFromDtor);
- throw TDtorException();
- }
- }
-
- TActorCoro::~TActorCoro() {
- Impl->Destroy();
- }
-
- STATEFN(TActorCoro::StateFunc) {
- if (Impl->ProcessEvent(ev)) {
- PassAway();
- }
- }
-}
diff --git a/library/cpp/actors/core/actor_coroutine.h b/library/cpp/actors/core/actor_coroutine.h
deleted file mode 100644
index a098c334cf..0000000000
--- a/library/cpp/actors/core/actor_coroutine.h
+++ /dev/null
@@ -1,230 +0,0 @@
-#pragma once
-
-#include <util/system/context.h>
-#include <util/system/filemap.h>
-
-#include "actor_bootstrapped.h"
-#include "executor_thread.h"
-#include "event_local.h"
-
-#include <thread>
-
-namespace NActors {
-
- class TActorCoro;
-
-#ifndef CORO_THROUGH_THREADS
-# ifdef _tsan_enabled_
-# define CORO_THROUGH_THREADS 1
-# else
-# define CORO_THROUGH_THREADS 0
-# endif
-#endif
-
- class TActorCoroImpl : public ITrampoLine {
- const bool AllowUnhandledDtor;
- bool Finished = false;
- bool InvokedFromDtor = false;
-#if CORO_THROUGH_THREADS
- TAutoEvent InEvent;
- TAutoEvent OutEvent;
- TActivationContext *ActivationContext = nullptr;
- std::thread WorkerThread;
-#else
- TMappedAllocation Stack;
- TContClosure FiberClosure;
- TExceptionSafeContext FiberContext;
- TExceptionSafeContext* ActorSystemContext = nullptr;
-#endif
- THolder<IEventHandle> PendingEvent;
-
- protected:
- TActorIdentity SelfActorId = TActorIdentity(TActorId());
- TActorId ParentActorId;
-
- // Pre-leave and pre-enter hook functions are called by coroutine actor code to conserve the state of required TLS
- // variables.
- //
- // They are called in the following order:
- //
- // 1. coroutine executes WaitForEvent
- // 2. StoreTlsState() is called
- // 3. control is returned to the actor system
- // 4. some event is received, handler called (now in different thread, unconserved TLS variables are changed!)
- // 5. handler transfers control to the coroutine
- // 6. RestoreTlsState() is called
- //
- // These hooks may be used in the following way:
- //
- // thread_local TMyClass *MyObject = nullptr;
- //
- // class TMyCoroImpl : public TActorCoroImpl {
- // TMyClass *SavedMyObject;
- // ...
- // public:
- // TMyCoroImpl()
- // : TActorCoroImpl(...)
- // {
- // StoreTlsState = RestoreTlsState = &TMyCoroImpl::ConserveState;
- // }
- //
- // static void ConserveState(TActorCoroImpl *p) {
- // TMyCoroImpl *my = static_cast<TMyCoroImpl*>(p);
- // std::swap(my->SavedMyObject, MyObject);
- // }
- //
- // ...
- // }
- void (*StoreTlsState)(TActorCoroImpl*) = nullptr;
- void (*RestoreTlsState)(TActorCoroImpl*) = nullptr;
-
-
- private:
- template <typename TFirstEvent, typename... TOtherEvents>
- struct TIsOneOf: public TIsOneOf<TOtherEvents...> {
- bool operator()(IEventHandle& ev) const {
- return ev.GetTypeRewrite() == TFirstEvent::EventType || TIsOneOf<TOtherEvents...>()(ev);
- }
- };
-
- template <typename TSingleEvent>
- struct TIsOneOf<TSingleEvent> {
- bool operator()(IEventHandle& ev) const {
- return ev.GetTypeRewrite() == TSingleEvent::EventType;
- }
- };
-
- protected:
- struct TDtorException : yexception {};
-
- public:
- TActorCoroImpl(size_t stackSize, bool allowUnhandledDtor = false);
- // specify stackSize explicitly for each actor; don't forget about overflow control gap
-
- virtual ~TActorCoroImpl() = default;
-
- virtual void Run() = 0;
-
- virtual void BeforeResume() {}
-
- // Release execution ownership and wait for some event to arrive.
- THolder<IEventHandle> WaitForEvent(TMonotonic deadline = TMonotonic::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, typename TCallback, typename = std::enable_if_t<std::is_invocable_v<TCallback, TAutoPtr<IEventHandle>>>>
- THolder<IEventHandle> WaitForSpecificEvent(TFunc&& filter, TCallback processUnexpectedEvent, TMonotonic deadline = TMonotonic::Max()) {
- for (;;) {
- if (THolder<IEventHandle> event = WaitForEvent(deadline); !event) {
- return nullptr;
- } else if (filter(*event)) {
- return event;
- } else {
- processUnexpectedEvent(event);
- }
- }
- }
-
- template <typename TFunc, typename TDerived, typename = std::enable_if_t<std::is_base_of_v<TActorCoroImpl, TDerived>>>
- THolder<IEventHandle> WaitForSpecificEvent(TFunc&& filter, void (TDerived::*processUnexpectedEvent)(TAutoPtr<IEventHandle>),
- TMonotonic deadline = TMonotonic::Max()) {
- auto callback = [&](TAutoPtr<IEventHandle> ev) { (static_cast<TDerived&>(*this).*processUnexpectedEvent)(ev); };
- return WaitForSpecificEvent(std::forward<TFunc>(filter), callback, deadline);
- }
-
- // 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, typename TCallback>
- THolder<IEventHandle> WaitForSpecificEvent(TCallback&& callback, TMonotonic deadline = TMonotonic::Max()) {
- TIsOneOf<TFirstEvent, TSecondEvent, TOtherEvents...> filter;
- return WaitForSpecificEvent(filter, std::forward<TCallback>(callback), deadline);
- }
-
- // Wait for single specific event.
- template <typename TEventType, typename TCallback>
- THolder<typename TEventType::THandle> WaitForSpecificEvent(TCallback&& callback, TMonotonic deadline = TMonotonic::Max()) {
- auto filter = [](IEventHandle& ev) {
- return ev.GetTypeRewrite() == TEventType::EventType;
- };
- THolder<IEventHandle> event = WaitForSpecificEvent(filter, std::forward<TCallback>(callback), deadline);
- return THolder<typename TEventType::THandle>(static_cast<typename TEventType::THandle*>(event ? event.Release() : nullptr));
- }
-
- protected: // Actor System compatibility section
- const TActorContext& GetActorContext() const { return TActivationContext::AsActorContext(); }
- TActorSystem *GetActorSystem() const { return GetActorContext().ExecutorThread.ActorSystem; }
- TInstant Now() const { return GetActorContext().Now(); }
- TMonotonic Monotonic() const { return GetActorContext().Monotonic(); }
-
- 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));
- }
-
- bool Send(const TActorId& recipient, THolder<IEventBase> 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);
-
- bool Forward(THolder<IEventHandle>& ev, const TActorId& recipient) {
- return Send(IEventHandle::Forward(ev, recipient).Release());
- }
-
- 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);
- }
-
- TActorId RegisterWithSameMailbox(IActor* actor) {
- return GetActorContext().RegisterWithSameMailbox(actor);
- }
-
- private:
- friend class TActorCoro;
- bool ProcessEvent(THolder<IEventHandle> ev);
- void Destroy();
-
- 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(THolder<IEventHandle> ev);
- THolder<IEventHandle> ReturnToActorSystem();
- void DoRun() override final;
- };
-
- class TActorCoro : public IActorCallback {
- THolder<TActorCoroImpl> Impl;
-
- public:
- template <class TEnumActivityType = IActor::EActivityType>
- TActorCoro(THolder<TActorCoroImpl> impl, const TEnumActivityType activityType = IActor::EActivityType::ACTOR_COROUTINE)
- : IActorCallback(static_cast<TReceiveFunc>(&TActorCoro::StateFunc), activityType)
- , Impl(std::move(impl))
- {}
-
- ~TActorCoro();
-
- TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parent) override {
- return new IEventHandle(TEvents::TSystem::Bootstrap, 0, self, parent, {}, 0);
- }
-
- private:
- STATEFN(StateFunc);
- };
-
-}
diff --git a/library/cpp/actors/core/actor_coroutine_ut.cpp b/library/cpp/actors/core/actor_coroutine_ut.cpp
deleted file mode 100644
index 4567cd142e..0000000000
--- a/library/cpp/actors/core/actor_coroutine_ut.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-#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;
-
-Y_UNIT_TEST_SUITE(ActorCoro) {
- 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;
-
- struct TPoisonPillException {};
-
- public:
- TCoroActor(TManualEvent& doneEvent, TAtomic& itemsProcessed)
- : TActorCoroImpl(1 << 20)
- , DoneEvent(doneEvent)
- , ItemsProcessed(itemsProcessed)
- , Finish(false)
- {
- }
-
- 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>(&TCoroActor::ProcessUnexpectedEvent);
- 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) {
- if (event->GetTypeRewrite() == Enough) {
- Finish = true;
- } else if (event->GetTypeRewrite() == TEvents::TSystem::Poison) {
- throw TPoisonPillException();
- }
- }
- };
-
- void Check(THolder<IEventBase> && message) {
- THolder<TActorSystemSetup> setup = MakeHolder<TActorSystemSetup>();
- 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;
- 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();
- }
-
- Y_UNIT_TEST(Basic) {
- if (NSan::TSanIsOn()) {
- // TODO https://st.yandex-team.ru/DEVTOOLS-3154
- return;
- }
- Check(MakeHolder<TEvEnough>());
- }
-
- Y_UNIT_TEST(PoisonPill) {
- Check(MakeHolder<TEvents::TEvPoisonPill>());
- }
-}
diff --git a/library/cpp/actors/core/actor_ut.cpp b/library/cpp/actors/core/actor_ut.cpp
deleted file mode 100644
index 52d3cbad9c..0000000000
--- a/library/cpp/actors/core/actor_ut.cpp
+++ /dev/null
@@ -1,511 +0,0 @@
-#include "actor.h"
-#include "events.h"
-#include "actorsystem.h"
-#include "executor_pool_basic.h"
-#include "scheduler_basic.h"
-#include "actor_bootstrapped.h"
-#include "actor_benchmark_helper.h"
-
-#include <library/cpp/actors/testlib/test_runtime.h>
-#include <library/cpp/actors/util/threadparkpad.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/generic/algorithm.h>
-#include <library/cpp/deprecated/atomic/atomic.h>
-#include <util/system/rwlock.h>
-#include <util/system/hp_timer.h>
-
-using namespace NActors;
-using namespace NActors::NTests;
-
-Y_UNIT_TEST_SUITE(ActorBenchmark) {
-
- using TActorBenchmark = ::NActors::NTests::TActorBenchmark<>;
- using TSettings = TActorBenchmark::TSettings;
- using TSendReceiveActorParams = TActorBenchmark::TSendReceiveActorParams;
-
- Y_UNIT_TEST(WithSharedExecutors) {
- THolder<TActorSystemSetup> setup = TActorBenchmark::GetActorSystemSetup(0, false);
- TActorBenchmark::AddBasicPool(setup, 2, 1, 0);
- TActorBenchmark::AddBasicPool(setup, 2, 1, 1);
-
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- TThreadParkPad pad;
- TAtomic actorsAlive = 0;
- THPTimer Timer;
-
- ui64 eventsPerPair = TSettings::TotalEventsAmountPerThread * 4 / 60;
-
- Timer.Reset();
- for (ui32 i = 0; i < 50; ++i) {
- ui32 followerPoolId = 0;
- ui32 leaderPoolId = 0;
- TActorId followerId = actorSystem.Register(
- new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{.OtherEvents=eventsPerPair / 2, .Allocation=true}
- ),
- TMailboxType::HTSwap,
- followerPoolId
- );
- THolder<IActor> leader{
- new TTestEndDecorator(THolder(new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{.OwnEvents=eventsPerPair / 2, .Receivers={followerId}, .Allocation=true}
- )),
- &pad,
- &actorsAlive)
- };
- actorSystem.Register(leader.Release(), TMailboxType::HTSwap, leaderPoolId);
- }
- for (ui32 i = 0; i < 10; ++i) {
- ui32 followerPoolId = 1;
- ui32 leaderPoolId = 1;
- TActorId followerId = actorSystem.Register(
- new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{.OtherEvents=eventsPerPair / 2, .Allocation=true}
- ),
- TMailboxType::HTSwap,
- followerPoolId
- );
- THolder<IActor> leader{
- new TTestEndDecorator(
- THolder(new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{.OwnEvents=eventsPerPair / 2, .Receivers={followerId}, .Allocation=true}
- )),
- &pad,
- &actorsAlive
- )
- };
- actorSystem.Register(leader.Release(), TMailboxType::HTSwap, leaderPoolId);
- }
-
- pad.Park();
- auto elapsedTime = Timer.Passed() / (TSettings::TotalEventsAmountPerThread * 4);
- actorSystem.Stop();
-
- Cerr << "Completed " << 1e9 * elapsedTime << Endl;
- }
-
- Y_UNIT_TEST(WithoutSharedExecutors) {
- THolder<TActorSystemSetup> setup = TActorBenchmark::GetActorSystemSetup(0, false);
- TActorBenchmark::AddBasicPool(setup, 2, 1, 0);
- TActorBenchmark::AddBasicPool(setup, 2, 1, 0);
-
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- TThreadParkPad pad;
- TAtomic actorsAlive = 0;
- THPTimer Timer;
-
- ui64 eventsPerPair = TSettings::TotalEventsAmountPerThread * 4 / 60;
-
- Timer.Reset();
- for (ui32 i = 0; i < 50; ++i) {
- ui32 followerPoolId = 0;
- ui32 leaderPoolId = 0;
- TActorId followerId = actorSystem.Register(
- new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{.OtherEvents=eventsPerPair / 2, .Allocation=true}
- ),
- TMailboxType::HTSwap,
- followerPoolId
- );
- THolder<IActor> leader{
- new TTestEndDecorator(
- THolder(new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{.OwnEvents=eventsPerPair / 2, .Receivers={followerId}, .Allocation=true}
- )),
- &pad,
- &actorsAlive
- )
- };
- actorSystem.Register(leader.Release(), TMailboxType::HTSwap, leaderPoolId);
- }
- for (ui32 i = 0; i < 10; ++i) {
- ui32 followerPoolId = 1;
- ui32 leaderPoolId = 1;
- TActorId followerId = actorSystem.Register(
- new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{.OtherEvents=eventsPerPair / 2, .Allocation=true}
- ),
- TMailboxType::HTSwap,
- followerPoolId
- );
- THolder<IActor> leader{
- new TTestEndDecorator(
- THolder(new TActorBenchmark::TSendReceiveActor(
- TSendReceiveActorParams{.OwnEvents=eventsPerPair / 2, .Receivers={followerId}, .Allocation=true}
- )),
- &pad,
- &actorsAlive
- )
- };
- actorSystem.Register(leader.Release(), TMailboxType::HTSwap, leaderPoolId);
- }
-
- pad.Park();
- auto elapsedTime = Timer.Passed() / (4 * TSettings::TotalEventsAmountPerThread);
- actorSystem.Stop();
-
- Cerr << "Completed " << 1e9 * elapsedTime << Endl;
- }
-
- Y_UNIT_TEST(SendReceive1Pool1ThreadAlloc) {
- for (const auto& mType : TSettings::MailboxTypes) {
- auto stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(true, mType, TActorBenchmark::EPoolType::Basic, ESendingType::Common);
- });
- Cerr << stats.ToString() << " " << mType << Endl;
- stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(true, mType, TActorBenchmark::EPoolType::Basic, ESendingType::Lazy);
- });
- Cerr << stats.ToString() << " " << mType << " Lazy" << Endl;
- stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(true, mType, TActorBenchmark::EPoolType::Basic, ESendingType::Tail);
- });
- Cerr << stats.ToString() << " " << mType << " Tail" << Endl;
- }
- }
-
- Y_UNIT_TEST(SendReceive1Pool1ThreadAllocUnited) {
- for (const auto& mType : TSettings::MailboxTypes) {
- auto stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(true, mType, TActorBenchmark::EPoolType::United, ESendingType::Common);
- });
- Cerr << stats.ToString() << " " << mType << Endl;
- stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(true, mType, TActorBenchmark::EPoolType::United, ESendingType::Lazy);
- });
- Cerr << stats.ToString() << " " << mType << " Lazy" << Endl;
- stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(true, mType, TActorBenchmark::EPoolType::United, ESendingType::Tail);
- });
- Cerr << stats.ToString() << " " << mType << " Tail" << Endl;
- }
- }
-
- Y_UNIT_TEST(SendReceive1Pool1ThreadNoAlloc) {
- for (const auto& mType : TSettings::MailboxTypes) {
- auto stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(false, mType, TActorBenchmark::EPoolType::Basic, ESendingType::Common);
- });
- Cerr << stats.ToString() << " " << mType << Endl;
- stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(false, mType, TActorBenchmark::EPoolType::Basic, ESendingType::Lazy);
- });
- Cerr << stats.ToString() << " " << mType << " Lazy" << Endl;
- stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(false, mType, TActorBenchmark::EPoolType::Basic, ESendingType::Tail);
- });
- Cerr << stats.ToString() << " " << mType << " Tail" << Endl;
- }
- }
-
- Y_UNIT_TEST(SendReceive1Pool1ThreadNoAllocUnited) {
- for (const auto& mType : TSettings::MailboxTypes) {
- auto stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(false, mType, TActorBenchmark::EPoolType::United, ESendingType::Common);
- });
- Cerr << stats.ToString() << " " << mType << Endl;
- stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(false, mType, TActorBenchmark::EPoolType::United, ESendingType::Lazy);
- });
- Cerr << stats.ToString() << " " << mType << " Lazy" << Endl;
- stats = TActorBenchmark::CountStats([mType] {
- return TActorBenchmark::BenchSendReceive(false, mType, TActorBenchmark::EPoolType::United, ESendingType::Tail);
- });
- Cerr << stats.ToString() << " " << mType << " Tail" << Endl;
- }
- }
-
- Y_UNIT_TEST(SendActivateReceive1Pool1ThreadAlloc) {
- TActorBenchmark::RunBenchSendActivateReceive(1, 1, true, TActorBenchmark::EPoolType::Basic);
- }
-
- Y_UNIT_TEST(SendActivateReceive1Pool1ThreadAllocUnited) {
- TActorBenchmark::RunBenchSendActivateReceive(1, 1, true, TActorBenchmark::EPoolType::United);
- }
-
- Y_UNIT_TEST(SendActivateReceive1Pool1ThreadNoAlloc) {
- TActorBenchmark::RunBenchSendActivateReceive(1, 1, false, TActorBenchmark::EPoolType::Basic);
- }
-
- Y_UNIT_TEST(SendActivateReceive1Pool1ThreadNoAllocUnited) {
- TActorBenchmark::RunBenchSendActivateReceive(1, 1, false, TActorBenchmark::EPoolType::United);
- }
-
- Y_UNIT_TEST(SendActivateReceive1Pool2ThreadsAlloc) {
- TActorBenchmark::RunBenchSendActivateReceive(1, 2, true, TActorBenchmark::EPoolType::Basic);
- }
-
- Y_UNIT_TEST(SendActivateReceive1Pool2ThreadsAllocUnited) {
- TActorBenchmark::RunBenchSendActivateReceive(1, 2, true, TActorBenchmark::EPoolType::United);
- }
-
- Y_UNIT_TEST(SendActivateReceive1Pool2ThreadsNoAlloc) {
- TActorBenchmark::RunBenchSendActivateReceive(1, 2, false, TActorBenchmark::EPoolType::Basic);
- }
-
- Y_UNIT_TEST(SendActivateReceive1Pool2ThreadsNoAllocUnited) {
- TActorBenchmark::RunBenchSendActivateReceive(1, 2, false, TActorBenchmark::EPoolType::United);
- }
-
- Y_UNIT_TEST(SendActivateReceive2Pool1ThreadAlloc) {
- TActorBenchmark::RunBenchSendActivateReceive(2, 1, true, TActorBenchmark::EPoolType::Basic);
- }
-
- Y_UNIT_TEST(SendActivateReceive2Pool1ThreadAllocUnited) {
- TActorBenchmark::RunBenchSendActivateReceive(2, 1, true, TActorBenchmark::EPoolType::United);
- }
-
- Y_UNIT_TEST(SendActivateReceive2Pool1ThreadNoAlloc) {
- TActorBenchmark::RunBenchSendActivateReceive(2, 1, false, TActorBenchmark::EPoolType::Basic);
- }
-
- Y_UNIT_TEST(SendActivateReceive2Pool1ThreadNoAllocUnited) {
- TActorBenchmark::RunBenchSendActivateReceive(2, 1, false, TActorBenchmark::EPoolType::United);
- }
-
- Y_UNIT_TEST(SendActivateReceive1Pool1Threads) { TActorBenchmark::RunBenchContentedThreads(1, TActorBenchmark::EPoolType::Basic); }
- Y_UNIT_TEST(SendActivateReceive1Pool1ThreadsUnited) { TActorBenchmark::RunBenchContentedThreads(1, TActorBenchmark::EPoolType::United); }
- Y_UNIT_TEST(SendActivateReceive1Pool2Threads) { TActorBenchmark::RunBenchContentedThreads(2, TActorBenchmark::EPoolType::Basic); }
- Y_UNIT_TEST(SendActivateReceive1Pool2ThreadsUnited) { TActorBenchmark::RunBenchContentedThreads(2, TActorBenchmark::EPoolType::United); }
- Y_UNIT_TEST(SendActivateReceive1Pool3Threads) { TActorBenchmark::RunBenchContentedThreads(3, TActorBenchmark::EPoolType::Basic); }
- Y_UNIT_TEST(SendActivateReceive1Pool3ThreadsUnited) { TActorBenchmark::RunBenchContentedThreads(3, TActorBenchmark::EPoolType::United); }
- Y_UNIT_TEST(SendActivateReceive1Pool4Threads) { TActorBenchmark::RunBenchContentedThreads(4, TActorBenchmark::EPoolType::Basic); }
- Y_UNIT_TEST(SendActivateReceive1Pool4ThreadsUnited) { TActorBenchmark::RunBenchContentedThreads(4, TActorBenchmark::EPoolType::United); }
- Y_UNIT_TEST(SendActivateReceive1Pool5Threads) { TActorBenchmark::RunBenchContentedThreads(5, TActorBenchmark::EPoolType::Basic); }
- Y_UNIT_TEST(SendActivateReceive1Pool5ThreadsUnited) { TActorBenchmark::RunBenchContentedThreads(5, TActorBenchmark::EPoolType::United); }
- Y_UNIT_TEST(SendActivateReceive1Pool6Threads) { TActorBenchmark::RunBenchContentedThreads(6, TActorBenchmark::EPoolType::Basic); }
- Y_UNIT_TEST(SendActivateReceive1Pool6ThreadsUnited) { TActorBenchmark::RunBenchContentedThreads(6, TActorBenchmark::EPoolType::United); }
- Y_UNIT_TEST(SendActivateReceive1Pool7Threads) { TActorBenchmark::RunBenchContentedThreads(7, TActorBenchmark::EPoolType::Basic); }
- Y_UNIT_TEST(SendActivateReceive1Pool7ThreadsUnited) { TActorBenchmark::RunBenchContentedThreads(7, TActorBenchmark::EPoolType::United); }
- Y_UNIT_TEST(SendActivateReceive1Pool8Threads) { TActorBenchmark::RunBenchContentedThreads(8, TActorBenchmark::EPoolType::Basic); }
- Y_UNIT_TEST(SendActivateReceive1Pool8ThreadsUnited) { TActorBenchmark::RunBenchContentedThreads(8, TActorBenchmark::EPoolType::United); }
-
- Y_UNIT_TEST(SendActivateReceiveCSV) {
- std::vector<ui32> threadsList;
- for (ui32 threads = 1; threads <= 32; threads *= 2) {
- threadsList.push_back(threads);
- }
- std::vector<ui32> actorPairsList;
- for (ui32 actorPairs = 1; actorPairs <= 2 * 32; actorPairs *= 2) {
- actorPairsList.push_back(actorPairs);
- }
- TActorBenchmark::RunSendActivateReceiveCSV(threadsList, actorPairsList, {1}, TDuration::MilliSeconds(100));
- }
-
- Y_UNIT_TEST(SendActivateReceiveWithMailboxNeighbours) {
- TVector<ui32> NeighbourActors = {0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 256};
- for (const auto& neighbour : NeighbourActors) {
- auto stats = TActorBenchmark::CountStats([neighbour] {
- return TActorBenchmark::BenchSendActivateReceiveWithMailboxNeighbours(neighbour, TActorBenchmark::EPoolType::Basic, ESendingType::Common);
- });
- Cerr << stats.ToString() << " neighbourActors: " << neighbour << Endl;
- stats = TActorBenchmark::CountStats([neighbour] {
- return TActorBenchmark::BenchSendActivateReceiveWithMailboxNeighbours(neighbour, TActorBenchmark::EPoolType::Basic, ESendingType::Lazy);
- });
- Cerr << stats.ToString() << " neighbourActors: " << neighbour << " Lazy" << Endl;
- stats = TActorBenchmark::CountStats([neighbour] {
- return TActorBenchmark::BenchSendActivateReceiveWithMailboxNeighbours(neighbour, TActorBenchmark::EPoolType::Basic, ESendingType::Tail);
- });
- Cerr << stats.ToString() << " neighbourActors: " << neighbour << " Tail" << Endl;
- }
- }
-
- Y_UNIT_TEST(SendActivateReceiveWithMailboxNeighboursUnited) {
- TVector<ui32> NeighbourActors = {0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 256};
- for (const auto& neighbour : NeighbourActors) {
- auto stats = TActorBenchmark::CountStats([neighbour] {
- return TActorBenchmark::BenchSendActivateReceiveWithMailboxNeighbours(neighbour, TActorBenchmark::EPoolType::United, ESendingType::Common);
- });
- Cerr << stats.ToString() << " neighbourActors: " << neighbour << Endl;
- stats = TActorBenchmark::CountStats([neighbour] {
- return TActorBenchmark::BenchSendActivateReceiveWithMailboxNeighbours(neighbour, TActorBenchmark::EPoolType::United, ESendingType::Lazy);
- });
- Cerr << stats.ToString() << " neighbourActors: " << neighbour << " Lazy" << Endl;
- stats = TActorBenchmark::CountStats([neighbour] {
- return TActorBenchmark::BenchSendActivateReceiveWithMailboxNeighbours(neighbour, TActorBenchmark::EPoolType::United, ESendingType::Tail);
- });
- Cerr << stats.ToString() << " neighbourActors: " << neighbour << " Tail" << Endl;
- }
- }
-}
-
-Y_UNIT_TEST_SUITE(TestDecorator) {
- struct TPingDecorator : TDecorator {
- TAutoPtr<IEventHandle> SavedEvent = nullptr;
- ui64* Counter;
-
- TPingDecorator(THolder<IActor>&& actor, ui64* counter)
- : TDecorator(std::move(actor))
- , Counter(counter)
- {
- }
-
- bool DoBeforeReceiving(TAutoPtr<IEventHandle>& ev, const TActorContext&) override {
- *Counter += 1;
- if (ev->Type != TEvents::THelloWorld::Pong) {
- TAutoPtr<IEventHandle> pingEv = new IEventHandle(SelfId(), SelfId(), new TEvents::TEvPing());
- SavedEvent = ev;
- Actor->Receive(pingEv);
- } else {
- Actor->Receive(SavedEvent);
- }
- return false;
- }
- };
-
- struct TPongDecorator : TDecorator {
- ui64* Counter;
-
- TPongDecorator(THolder<IActor>&& actor, ui64* counter)
- : TDecorator(std::move(actor))
- , Counter(counter)
- {
- }
-
- bool DoBeforeReceiving(TAutoPtr<IEventHandle>& ev, const TActorContext&) override {
- *Counter += 1;
- if (ev->Type == TEvents::THelloWorld::Ping) {
- TAutoPtr<IEventHandle> pongEv = new IEventHandle(SelfId(), SelfId(), new TEvents::TEvPong());
- Send(SelfId(), new TEvents::TEvPong());
- return false;
- }
- return true;
- }
- };
-
- struct TTestActor : TActorBootstrapped<TTestActor> {
- static constexpr char ActorName[] = "TestActor";
-
- void Bootstrap()
- {
- const auto& activityTypeIndex = GetActivityType();
- Y_ENSURE(activityTypeIndex < GetActivityTypeCount());
- Y_ENSURE(GetActivityTypeName(activityTypeIndex) == "TestActor");
- PassAway();
- }
- };
-
- Y_UNIT_TEST(Basic) {
- THolder<TActorSystemSetup> setup = MakeHolder<TActorSystemSetup>();
- setup->NodeId = 0;
- setup->ExecutorsCount = 1;
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[setup->ExecutorsCount]);
-
- ui64 ts = GetCycleCountFast();
- THolder<IHarmonizer> harmonizer(MakeHarmonizer(ts));
- for (ui32 i = 0; i < setup->ExecutorsCount; ++i) {
- setup->Executors[i] = new TBasicExecutorPool(i, 1, 10, "basic", harmonizer.Get());
- harmonizer->AddPool(setup->Executors[i].Get());
- }
- setup->Scheduler = new TBasicSchedulerThread;
-
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- THolder<IActor> innerActor = MakeHolder<TTestActor>();
- ui64 pongCounter = 0;
- THolder<IActor> pongActor = MakeHolder<TPongDecorator>(std::move(innerActor), &pongCounter);
- ui64 pingCounter = 0;
- THolder<IActor> pingActor = MakeHolder<TPingDecorator>(std::move(pongActor), &pingCounter);
-
- TThreadParkPad pad;
- TAtomic actorsAlive = 0;
-
- THolder<IActor> endActor = MakeHolder<TTestEndDecorator>(std::move(pingActor), &pad, &actorsAlive);
- actorSystem.Register(endActor.Release(), TMailboxType::HTSwap);
-
- pad.Park();
- actorSystem.Stop();
- UNIT_ASSERT(pongCounter == 2 && pingCounter == 2);
- }
-
- Y_UNIT_TEST(LocalProcessKey) {
- static constexpr char ActorName[] = "TestActor";
-
- UNIT_ASSERT((TEnumProcessKey<TActorActivityTag, IActor::EActorActivity>::GetName(IActor::EActivityType::INTERCONNECT_PROXY_TCP) == "INTERCONNECT_PROXY_TCP"));
- UNIT_ASSERT((TLocalProcessKey<TActorActivityTag, ActorName>::GetName() == ActorName));
- }
-}
-
-Y_UNIT_TEST_SUITE(TestStateFunc) {
- struct TTestActorWithExceptionsStateFunc : TActor<TTestActorWithExceptionsStateFunc> {
- static constexpr char ActorName[] = "TestActorWithExceptionsStateFunc";
-
- TTestActorWithExceptionsStateFunc()
- : TActor<TTestActorWithExceptionsStateFunc>(&TTestActorWithExceptionsStateFunc::StateFunc)
- {
- }
-
- STRICT_STFUNC_EXC(StateFunc,
- hFunc(TEvents::TEvWakeup, Handle),
- ExceptionFunc(yexception, HandleException)
- ExceptionFuncEv(std::exception, HandleException)
- AnyExceptionFunc(HandleException)
- )
-
- void Handle(TEvents::TEvWakeup::TPtr& ev) {
- Owner = ev->Sender;
- switch (ev->Get()->Tag) {
- case ETag::NoException:
- SendResponse(ETag::NoException);
- break;
- case ETag::YException:
- Cerr << "Throw yexception" << Endl;
- throw yexception();
- case ETag::StdException:
- Cerr << "Throw std::exception" << Endl;
- throw std::runtime_error("trololo");
- case ETag::OtherException:
- Cerr << "Throw trash" << Endl;
- throw TString("1");
- default:
- UNIT_ASSERT(false);
- }
- }
-
- void HandleException(const yexception&) {
- Cerr << "Handle yexception" << Endl;
- SendResponse(ETag::YException);
- }
-
- void HandleException(const std::exception&, TAutoPtr<::NActors::IEventHandle>& ev) {
- Cerr << "Handle std::exception from event with type " << ev->Type << Endl;
- SendResponse(ETag::StdException);
- }
-
- void HandleException() {
- Cerr << "Handle trash" << Endl;
- SendResponse(ETag::OtherException);
- }
-
- enum ETag : ui64 {
- NoException,
- YException,
- StdException,
- OtherException,
- };
-
- void SendResponse(ETag tag) {
- Send(Owner, new TEvents::TEvWakeup(tag));
- }
-
- TActorId Owner;
- };
-
- Y_UNIT_TEST(StateFuncWithExceptions) {
- TTestActorRuntimeBase runtime;
- runtime.Initialize();
- auto sender = runtime.AllocateEdgeActor();
- auto testActor = runtime.Register(new TTestActorWithExceptionsStateFunc());
- for (ui64 tag = 0; tag < 4; ++tag) {
- runtime.Send(new IEventHandle(testActor, sender, new TEvents::TEvWakeup(tag)), 0, true);
- auto ev = runtime.GrabEdgeEventRethrow<TEvents::TEvWakeup>(sender);
- UNIT_ASSERT_VALUES_EQUAL(ev->Get()->Tag, tag);
- }
- }
-}
diff --git a/library/cpp/actors/core/actor_virtual.cpp b/library/cpp/actors/core/actor_virtual.cpp
deleted file mode 100644
index 709cd7be15..0000000000
--- a/library/cpp/actors/core/actor_virtual.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "actor_virtual.h"
-
-namespace NActors {
-
-
-}
diff --git a/library/cpp/actors/core/actor_virtual.h b/library/cpp/actors/core/actor_virtual.h
deleted file mode 100644
index 78da45138d..0000000000
--- a/library/cpp/actors/core/actor_virtual.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#pragma once
-#include "event.h"
-#include "actor.h"
-
-namespace NActors {
-
-template <class TEvent>
-class TEventContext {
-private:
- TEvent* Event;
- std::unique_ptr<IEventHandle> Handle;
-public:
- const TEvent* operator->() const {
- return Event;
- }
- const IEventHandle& GetHandle() const {
- return *Handle;
- }
- TEventContext(std::unique_ptr<IEventHandle> handle)
- : Handle(std::move(handle))
- {
- Y_DEBUG_ABORT_UNLESS(dynamic_cast<TEvent*>(Handle->GetBase()));
- Event = static_cast<TEvent*>(Handle->GetBase());
- Y_ABORT_UNLESS(Event);
- }
-};
-
-template <class TEvent, class TExpectedActor>
-class IEventForActor: public IEventBase {
-protected:
- virtual bool DoExecute(IActor* actor, std::unique_ptr<IEventHandle> eventPtr) override {
- Y_DEBUG_ABORT_UNLESS(dynamic_cast<TExpectedActor*>(actor));
- auto* actorCorrect = static_cast<TExpectedActor*>(actor);
- TEventContext<TEvent> context(std::move(eventPtr));
- actorCorrect->ProcessEvent(context);
- return true;
- }
-public:
-};
-
-template <class TBaseEvent, class TEvent, class TExpectedObject>
-class IEventForAnything: public TBaseEvent {
-protected:
- virtual bool DoExecute(IActor* actor, std::unique_ptr<IEventHandle> eventPtr) override {
- auto* objImpl = dynamic_cast<TExpectedObject*>(actor);
- if (!objImpl) {
- return false;
- }
- TEventContext<TEvent> context(std::move(eventPtr));
- objImpl->ProcessEvent(context);
- return true;
- }
-public:
-};
-
-template <class TEvent, class TActor>
-class TEventLocalForActor: public IEventForActor<TEvent, TActor> {
-private:
- using TBase = IEventForActor<TEvent, TActor>;
- static TString GetClassTitle() {
- return TStringBuilder() << typeid(TEvent).name() << "->" << typeid(TActor).name();
- }
- static i64 LocalClassId;
-public:
- virtual ui32 Type() const override {
- return LocalClassId;
- }
- virtual TString ToStringHeader() const override {
- return GetClassTitle();
- }
-
- virtual bool SerializeToArcadiaStream(TChunkSerializer* /*serializer*/) const override {
- Y_ABORT("Serialization of local event %s->%s", typeid(TEvent).name(), typeid(TActor).name());
- }
-
- virtual bool IsSerializable() const override {
- return false;
- }
-
- static IEventBase* Load(TEventSerializedData*) {
- Y_ABORT("Loading of local event %s->%s", typeid(TEvent).name(), typeid(TActor).name());
- }
-};
-
-template <class TEvent, class TActor>
-i64 TEventLocalForActor<TEvent, TActor>::LocalClassId = Singleton<TAtomicCounter>()->Inc();
-
-}
diff --git a/library/cpp/actors/core/actorid.cpp b/library/cpp/actors/core/actorid.cpp
deleted file mode 100644
index ccda035eac..0000000000
--- a/library/cpp/actors/core/actorid.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "actorid.h"
-#include <util/string/builder.h>
-#include <util/string/cast.h>
-
-namespace NActors {
- void TActorId::Out(IOutputStream& o) const {
- o << "[" << NodeId() << ":" << LocalId() << ":" << Hint() << "]";
- }
-
- TString TActorId::ToString() const {
- TString x;
- TStringOutput o(x);
- Out(o);
- return x;
- }
-
- bool TActorId::Parse(const char* buf, ui32 sz) {
- if (sz < 4 || buf[0] != '[' || buf[sz - 1] != ']')
- return false;
-
- size_t semicolons[2];
- TStringBuf str(buf, sz);
- semicolons[0] = str.find(':', 1);
- if (semicolons[0] == TStringBuf::npos)
- return false;
- semicolons[1] = str.find(':', semicolons[0] + 1);
- if (semicolons[1] == TStringBuf::npos)
- return false;
-
- bool success = TryFromString(buf + 1, semicolons[0] - 1, Raw.N.NodeId) && TryFromString(buf + semicolons[0] + 1, semicolons[1] - semicolons[0] - 1, Raw.N.LocalId) && TryFromString(buf + semicolons[1] + 1, sz - semicolons[1] - 2, Raw.N.Hint);
-
- return success;
- }
-}
diff --git a/library/cpp/actors/core/actorid.h b/library/cpp/actors/core/actorid.h
deleted file mode 100644
index 4e9a7bc3c3..0000000000
--- a/library/cpp/actors/core/actorid.h
+++ /dev/null
@@ -1,198 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include <util/stream/output.h> // for IOutputStream
-#include <util/generic/hash.h>
-
-namespace NActors {
- // used as global uniq address of actor
- // also could be used to transport service id (12 byte strings placed in hint-localid)
- // highest 1 bit of node - mark of service id
- // next 11 bits of node-id - pool id
- // next 20 bits - node id itself
-
- struct TActorId {
- static constexpr ui32 MaxServiceIDLength = 12;
- static constexpr ui32 MaxPoolID = 0x000007FF;
- static constexpr ui32 MaxNodeId = 0x000FFFFF;
- static constexpr ui32 PoolIndexShift = 20;
- static constexpr ui32 PoolIndexMask = MaxPoolID << PoolIndexShift;
- static constexpr ui32 ServiceMask = 0x80000000;
- static constexpr ui32 NodeIdMask = MaxNodeId;
-
- private:
- union {
- struct {
- ui64 LocalId;
- ui32 Hint;
- ui32 NodeId;
- } N;
-
- struct {
- ui64 X1;
- ui64 X2;
- } X;
-
- ui8 Buf[16];
- } Raw;
-
- public:
- TActorId() noexcept {
- Raw.X.X1 = 0;
- Raw.X.X2 = 0;
- }
-
- explicit TActorId(ui32 nodeId, ui32 poolId, ui64 localId, ui32 hint) noexcept {
- Y_DEBUG_ABORT_UNLESS(poolId <= MaxPoolID);
- Raw.N.LocalId = localId;
- Raw.N.Hint = hint;
- Raw.N.NodeId = nodeId | (poolId << PoolIndexShift);
- }
-
- explicit TActorId(ui32 nodeId, const TStringBuf& x) noexcept {
- Y_ABORT_UNLESS(x.size() <= MaxServiceIDLength, "service id is too long");
- Raw.N.LocalId = 0;
- Raw.N.Hint = 0;
- Raw.N.NodeId = nodeId | ServiceMask;
- memcpy(Raw.Buf, x.data(), x.size());
- }
-
- explicit TActorId(ui64 x1, ui64 x2) noexcept {
- Raw.X.X1 = x1;
- Raw.X.X2 = x2;
- }
-
- explicit operator bool() const noexcept {
- return Raw.X.X1 != 0 || Raw.X.X2 != 0;
- }
-
- ui64 LocalId() const noexcept {
- return Raw.N.LocalId;
- }
-
- ui32 Hint() const noexcept {
- return Raw.N.Hint;
- }
-
- ui32 NodeId() const noexcept {
- return Raw.N.NodeId & NodeIdMask;
- }
-
- bool IsService() const noexcept {
- return (Raw.N.NodeId & ServiceMask);
- }
-
- TStringBuf ServiceId() const noexcept {
- Y_DEBUG_ABORT_UNLESS(IsService());
- return TStringBuf((const char*)Raw.Buf, MaxServiceIDLength);
- }
-
- static ui32 PoolIndex(ui32 nodeid) noexcept {
- return ((nodeid & PoolIndexMask) >> PoolIndexShift);
- }
-
- ui32 PoolID() const noexcept {
- return PoolIndex(Raw.N.NodeId);
- }
-
- ui64 RawX1() const noexcept {
- return Raw.X.X1;
- }
-
- ui64 RawX2() const noexcept {
- return Raw.X.X2;
- }
-
- bool operator<(const TActorId& x) const noexcept {
- const ui64 s1 = Raw.X.X1;
- const ui64 s2 = Raw.X.X2;
- const ui64 x1 = x.Raw.X.X1;
- const ui64 x2 = x.Raw.X.X2;
-
- return (s1 != x1) ? (s1 < x1) : (s2 < x2);
- }
-
- bool operator!=(const TActorId& x) const noexcept {
- return Raw.X.X1 != x.Raw.X.X1 || Raw.X.X2 != x.Raw.X.X2;
- }
-
- bool operator==(const TActorId& x) const noexcept {
- return !(x != *this);
- }
-
- ui64 Hash() const noexcept {
- const ui32* x = (const ui32*)Raw.Buf;
-
- const ui64 x1 = x[0] * 0x001DFF3D8DC48F5Dull;
- const ui64 x2 = x[1] * 0x179CA10C9242235Dull;
- const ui64 x3 = x[2] * 0x0F530CAD458B0FB1ull;
- const ui64 x4 = x[3] * 0xB5026F5AA96619E9ull;
-
- const ui64 z1 = x1 + x2;
- const ui64 z2 = x3 + x4;
-
- const ui64 sum = 0x5851F42D4C957F2D + z1 + z2;
-
- return (sum >> 32) | (sum << 32);
- }
-
- ui32 Hash32() const noexcept {
- const ui32* x = (const ui32*)Raw.Buf;
-
- const ui64 x1 = x[0] * 0x001DFF3D8DC48F5Dull;
- const ui64 x2 = x[1] * 0x179CA10C9242235Dull;
- const ui64 x3 = x[2] * 0x0F530CAD458B0FB1ull;
- const ui64 x4 = x[3] * 0xB5026F5AA96619E9ull;
-
- const ui64 z1 = x1 + x2;
- const ui64 z2 = x3 + x4;
-
- const ui64 sum = 0x5851F42D4C957F2D + z1 + z2;
-
- return sum >> 32;
- }
-
- struct THash {
- ui64 operator()(const TActorId& actorId) const noexcept {
- return actorId.Hash();
- }
- };
-
- struct THash32 {
- ui64 operator()(const TActorId& actorId) const noexcept {
- return actorId.Hash();
- }
- };
-
- struct TOrderedCmp {
- bool operator()(const TActorId &left, const TActorId &right) const noexcept {
- Y_DEBUG_ABORT_UNLESS(!left.IsService() && !right.IsService(), "ordered compare works for plain actorids only");
- const ui32 n1 = left.NodeId();
- const ui32 n2 = right.NodeId();
-
- return (n1 != n2) ? (n1 < n2) : left.LocalId() < right.LocalId();
- }
- };
-
- TString ToString() const;
- void Out(IOutputStream& o) const;
- bool Parse(const char* buf, ui32 sz);
- };
-
- static_assert(sizeof(TActorId) == 16, "expect sizeof(TActorId) == 16");
- static_assert(MaxPools < TActorId::MaxPoolID); // current implementation of united pool has limit MaxPools on pool id
-}
-
-template <>
-inline void Out<NActors::TActorId>(IOutputStream& o, const NActors::TActorId& x) {
- return x.Out(o);
-}
-
-template <>
-struct THash<NActors::TActorId> {
- inline ui64 operator()(const NActors::TActorId& x) const {
- return x.Hash();
- }
-};
-
-template<> struct std::hash<NActors::TActorId> : THash<NActors::TActorId> {};
diff --git a/library/cpp/actors/core/actorsystem.cpp b/library/cpp/actors/core/actorsystem.cpp
deleted file mode 100644
index c09a208ef5..0000000000
--- a/library/cpp/actors/core/actorsystem.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-#include "defs.h"
-#include "actorsystem.h"
-#include "callstack.h"
-#include "cpu_manager.h"
-#include "mailbox.h"
-#include "events.h"
-#include "interconnect.h"
-#include "servicemap.h"
-#include "scheduler_queue.h"
-#include "scheduler_actor.h"
-#include "log.h"
-#include "probes.h"
-#include "ask.h"
-#include <library/cpp/actors/util/affinity.h>
-#include <library/cpp/actors/util/datetime.h>
-#include <util/generic/hash.h>
-#include <util/system/rwlock.h>
-#include <util/random/random.h>
-
-namespace NActors {
- LWTRACE_USING(ACTORLIB_PROVIDER);
-
- TActorSetupCmd::TActorSetupCmd()
- : MailboxType(TMailboxType::HTSwap)
- , PoolId(0)
- , Actor(nullptr)
- {
- }
-
- TActorSetupCmd::TActorSetupCmd(TActorSetupCmd&&) = default;
- TActorSetupCmd& TActorSetupCmd::operator=(TActorSetupCmd&&) = default;
- TActorSetupCmd::~TActorSetupCmd() = default;
-
- TActorSetupCmd::TActorSetupCmd(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId)
- : MailboxType(mailboxType)
- , PoolId(poolId)
- , Actor(actor)
- {
- }
-
- TActorSetupCmd::TActorSetupCmd(std::unique_ptr<IActor> actor, TMailboxType::EType mailboxType, ui32 poolId)
- : MailboxType(mailboxType)
- , PoolId(poolId)
- , Actor(std::move(actor))
- {
- }
-
- void TActorSetupCmd::Set(std::unique_ptr<IActor> actor, TMailboxType::EType mailboxType, ui32 poolId) {
- MailboxType = mailboxType;
- PoolId = poolId;
- Actor = std::move(actor);
- }
-
- struct TActorSystem::TServiceMap : TNonCopyable {
- NActors::TServiceMap<TActorId, TActorId, TActorId::THash> LocalMap;
- TTicketLock Lock;
-
- TActorId RegisterLocalService(const TActorId& serviceId, const TActorId& actorId) {
- TTicketLock::TGuard guard(&Lock);
- const TActorId old = LocalMap.Update(serviceId, actorId);
- return old;
- }
-
- TActorId LookupLocal(const TActorId& x) {
- return LocalMap.Find(x);
- }
- };
-
- TActorSystem::TActorSystem(THolder<TActorSystemSetup>& setup, void* appData,
- TIntrusivePtr<NLog::TSettings> loggerSettings)
- : NodeId(setup->NodeId)
- , CpuManager(new TCpuManager(setup))
- , ExecutorPoolCount(CpuManager->GetExecutorsCount())
- , Scheduler(setup->Scheduler)
- , InterconnectCount((ui32)setup->Interconnect.ProxyActors.size())
- , CurrentTimestamp(0)
- , CurrentMonotonic(0)
- , CurrentIDCounter(RandomNumber<ui64>())
- , SystemSetup(setup.Release())
- , DefSelfID(NodeId, "actorsystem")
- , AppData0(appData)
- , LoggerSettings0(loggerSettings)
- , StartExecuted(false)
- , StopExecuted(false)
- , CleanupExecuted(false)
- {
- ServiceMap.Reset(new TServiceMap());
- }
-
- TActorSystem::~TActorSystem() {
- Cleanup();
- }
-
- template <TActorSystem::TEPSendFunction EPSpecificSend>
- bool TActorSystem::GenericSend(TAutoPtr<IEventHandle> ev) const {
- if (Y_UNLIKELY(!ev))
- return false;
-
-#ifdef USE_ACTOR_CALLSTACK
- ev->Callstack.TraceIfEmpty();
-#endif
-
- TActorId recipient = ev->GetRecipientRewrite();
- const ui32 recpNodeId = recipient.NodeId();
-
- if (recpNodeId != NodeId && recpNodeId != 0) {
- // if recipient is not local one - rewrite with forward instruction
- Y_DEBUG_ABORT_UNLESS(!ev->HasEvent() || ev->GetBase()->IsSerializable());
- Y_ABORT_UNLESS(ev->Recipient == recipient,
- "Event rewrite from %s to %s would be lost via interconnect",
- ev->Recipient.ToString().c_str(),
- 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);
- }
-
- Y_DEBUG_ABORT_UNLESS(recipient == ev->GetRecipientRewrite());
- const ui32 recpPool = recipient.PoolID();
- if (recipient && recpPool < ExecutorPoolCount) {
- if ((CpuManager->GetExecutorPool(recpPool)->*EPSpecificSend)(ev)) {
- return true;
- }
- }
- if (ev) {
- Send(IEventHandle::ForwardOnNondelivery(ev, TEvents::TEvUndelivered::ReasonActorUnknown));
- }
- return false;
- }
-
- template
- bool TActorSystem::GenericSend<&IExecutorPool::Send>(TAutoPtr<IEventHandle> ev) const;
- template
- bool TActorSystem::GenericSend<&IExecutorPool::SpecificSend>(TAutoPtr<IEventHandle> ev) const;
-
- bool TActorSystem::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie) const {
- return this->Send(new IEventHandle(recipient, DefSelfID, ev, flags, cookie));
- }
-
- bool TActorSystem::SpecificSend(TAutoPtr<IEventHandle> ev) const {
- return this->GenericSend<&IExecutorPool::SpecificSend>(ev);
- }
-
- bool TActorSystem::SpecificSend(TAutoPtr<IEventHandle> ev, ESendingType sendingType) const {
- if (!TlsThreadContext) {
- return this->GenericSend<&IExecutorPool::Send>(ev);
- } else {
- ESendingType previousType = std::exchange(TlsThreadContext->SendingType, sendingType);
- bool isSent = this->GenericSend<&IExecutorPool::SpecificSend>(ev);
- TlsThreadContext->SendingType = previousType;
- return isSent;
- }
- }
-
- void TActorSystem::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) const {
- Schedule(deadline - Timestamp(), ev, cookie);
- }
-
- void TActorSystem::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) const {
- const auto current = Monotonic();
- if (deadline < current)
- deadline = current;
-
- TTicketLock::TGuard guard(&ScheduleLock);
- ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie);
- }
-
- void TActorSystem::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) const {
- const auto deadline = Monotonic() + delta;
-
- TTicketLock::TGuard guard(&ScheduleLock);
- ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie);
- }
-
- NThreading::TFuture<THolder<IEventBase>> TActorSystem::AskGeneric(TMaybe<ui32> expectedEventType,
- TActorId recipient, THolder<IEventBase> event,
- TDuration timeout) {
- auto promise = NThreading::NewPromise<THolder<IEventBase>>();
- Register(MakeAskActor(expectedEventType, recipient, std::move(event), timeout, promise).Release());
- return promise.GetFuture();
- }
-
- ui64 TActorSystem::AllocateIDSpace(ui64 count) {
- Y_DEBUG_ABORT_UNLESS(count < Max<ui32>() / 65536);
-
- static_assert(sizeof(TAtomic) == sizeof(ui64), "expect sizeof(TAtomic) == sizeof(ui64)");
-
- // get high 32 bits as seconds from epoch
- // it could wrap every century, but we don't expect any actor-reference to live this long so such wrap will do no harm
- const ui64 timeFromEpoch = TInstant::MicroSeconds(RelaxedLoad(&CurrentTimestamp)).Seconds();
-
- // get low 32 bits as counter value
- ui32 lowPartEnd = (ui32)(AtomicAdd(CurrentIDCounter, count));
- while (lowPartEnd < count) // if our request crosses 32bit boundary - retry
- lowPartEnd = (ui32)(AtomicAdd(CurrentIDCounter, count));
-
- const ui64 lowPart = lowPartEnd - count;
- const ui64 ret = (timeFromEpoch << 32) | lowPart;
-
- return ret;
- }
-
- TActorId TActorSystem::InterconnectProxy(ui32 destinationNode) const {
- if (destinationNode < InterconnectCount)
- return Interconnect[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
- for (ui32 i = 0; i < InterconnectCount; ++i) {
- Send(eventFabric(Interconnect[i]));
- }
- return InterconnectCount;
- }
-
- TActorId TActorSystem::LookupLocalService(const TActorId& x) const {
- return ServiceMap->LookupLocal(x);
- }
-
- TActorId TActorSystem::RegisterLocalService(const TActorId& serviceId, const TActorId& actorId) {
- // TODO: notify old actor about demotion
- return ServiceMap->RegisterLocalService(serviceId, actorId);
- }
-
- void TActorSystem::GetPoolStats(ui32 poolId, TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const {
- CpuManager->GetPoolStats(poolId, poolStats, statsCopy);
- }
-
- THarmonizerStats TActorSystem::GetHarmonizerStats() const {
- return CpuManager->GetHarmonizerStats();
-
- }
-
- void TActorSystem::Start() {
- Y_ABORT_UNLESS(StartExecuted == false);
- StartExecuted = true;
-
- ScheduleQueue.Reset(new NSchedulerQueue::TQueueType());
- TVector<NSchedulerQueue::TReader*> scheduleReaders;
- scheduleReaders.push_back(&ScheduleQueue->Reader);
- CpuManager->PrepareStart(scheduleReaders, this);
- Scheduler->Prepare(this, &CurrentTimestamp, &CurrentMonotonic);
- Scheduler->PrepareSchedules(&scheduleReaders.front(), (ui32)scheduleReaders.size());
-
- // setup interconnect proxies
- {
- TInterconnectSetup& setup = SystemSetup->Interconnect;
- Interconnect.Reset(new TActorId[InterconnectCount + 1]);
- for (ui32 i = 0, e = InterconnectCount; i != e; ++i) {
- TActorSetupCmd& x = setup.ProxyActors[i];
- if (x.Actor) {
- Interconnect[i] = Register(x.Actor.release(), x.MailboxType, x.PoolId, i);
- Y_ABORT_UNLESS(!!Interconnect[i]);
- }
- }
- ProxyWrapperFactory = std::move(SystemSetup->Interconnect.ProxyWrapperFactory);
- }
-
- // setup local services
- {
- for (ui32 i = 0, e = (ui32)SystemSetup->LocalServices.size(); i != e; ++i) {
- std::pair<TActorId, TActorSetupCmd>& x = SystemSetup->LocalServices[i];
- const TActorId xid = Register(x.second.Actor.release(), x.second.MailboxType, x.second.PoolId, i);
- Y_ABORT_UNLESS(!!xid);
- if (!!x.first)
- RegisterLocalService(x.first, xid);
- }
- }
-
- Scheduler->PrepareStart();
- CpuManager->Start();
- Send(MakeSchedulerActorId(), new TEvSchedulerInitialize(scheduleReaders, &CurrentTimestamp, &CurrentMonotonic));
- Scheduler->Start();
- }
-
- void TActorSystem::Stop() {
- if (StopExecuted || !StartExecuted)
- return;
-
- StopExecuted = true;
-
- for (auto&& fn : std::exchange(DeferredPreStop, {})) {
- fn();
- }
-
- Scheduler->PrepareStop();
- CpuManager->PrepareStop();
- Scheduler->Stop();
- CpuManager->Shutdown();
- }
-
- void TActorSystem::Cleanup() {
- Stop();
- if (CleanupExecuted || !StartExecuted)
- return;
- CleanupExecuted = true;
- CpuManager->Cleanup();
- Scheduler.Destroy();
- }
-}
diff --git a/library/cpp/actors/core/actorsystem.h b/library/cpp/actors/core/actorsystem.h
deleted file mode 100644
index df5de39090..0000000000
--- a/library/cpp/actors/core/actorsystem.h
+++ /dev/null
@@ -1,311 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-#include "balancer.h"
-#include "config.h"
-#include "event.h"
-#include "executor_pool.h"
-#include "log_settings.h"
-#include "scheduler_cookie.h"
-#include "cpu_manager.h"
-#include "executor_thread.h"
-
-#include <library/cpp/threading/future/future.h>
-#include <library/cpp/actors/util/ticket_lock.h>
-
-#include <util/generic/vector.h>
-#include <util/datetime/base.h>
-#include <util/system/mutex.h>
-
-namespace NActors {
- class IActor;
- class TActorSystem;
- class TCpuManager;
- struct TWorkerContext;
-
- 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;
- }
-
- namespace NSchedulerQueue {
- class TReader;
- struct TQueueType;
- }
-
- // could be proxy to in-pool schedulers (for NUMA-aware executors)
- class ISchedulerThread : TNonCopyable {
- public:
- virtual ~ISchedulerThread() {
- }
-
- virtual void Prepare(TActorSystem* actorSystem, volatile ui64* currentTimestamp, volatile ui64* currentMonotonic) = 0;
- virtual void PrepareSchedules(NSchedulerQueue::TReader** readers, ui32 scheduleReadersCount) = 0;
- virtual void PrepareStart() { /* empty */ }
- virtual void Start() = 0;
- virtual void PrepareStop() = 0;
- virtual void Stop() = 0;
- };
-
- struct TActorSetupCmd {
- TMailboxType::EType MailboxType;
- ui32 PoolId;
- std::unique_ptr<IActor> Actor;
-
- TActorSetupCmd();
- TActorSetupCmd(const TActorSetupCmd&) = delete;
- TActorSetupCmd(TActorSetupCmd&&);
- TActorSetupCmd& operator=(const TActorSetupCmd&) = delete;
- TActorSetupCmd& operator=(TActorSetupCmd&&);
- TActorSetupCmd(std::unique_ptr<IActor> actor, TMailboxType::EType mailboxType, ui32 poolId);
- ~TActorSetupCmd();
-
- // For legacy code, please do not use
- TActorSetupCmd(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId);
-
- void Set(std::unique_ptr<IActor> actor, TMailboxType::EType mailboxType, ui32 poolId);
- };
-
- using TProxyWrapperFactory = std::function<TActorId(TActorSystem*, ui32)>;
-
- struct TInterconnectSetup {
- TVector<TActorSetupCmd> ProxyActors;
- TProxyWrapperFactory ProxyWrapperFactory;
- };
-
- struct TActorSystemSetup {
- ui32 NodeId = 0;
-
- // Either Executors or CpuManager must be initialized
- ui32 ExecutorsCount = 0;
- TArrayHolder<TAutoPtr<IExecutorPool>> Executors;
-
- TAutoPtr<IBalancer> Balancer; // main implementation will be implicitly created if not set
-
- TCpuManagerConfig CpuManager;
-
- TAutoPtr<ISchedulerThread> Scheduler;
-
- TInterconnectSetup Interconnect;
-
- bool MonitorStuckActors = false;
-
- using TLocalServices = TVector<std::pair<TActorId, TActorSetupCmd>>;
- TLocalServices LocalServices;
-
- ui32 GetExecutorsCount() const {
- return Executors ? ExecutorsCount : CpuManager.GetExecutorsCount();
- }
-
- TString GetPoolName(ui32 poolId) const {
- return Executors ? Executors[poolId]->GetName() : CpuManager.GetPoolName(poolId);
- }
-
- ui32 GetThreads(ui32 poolId) const {
- auto result = GetThreadsOptional(poolId);
- Y_ABORT_UNLESS(result, "undefined pool id: %" PRIu32, (ui32)poolId);
- return *result;
- }
-
- std::optional<ui32> GetThreadsOptional(const ui32 poolId) const {
- if (Y_LIKELY(Executors)) {
- if (Y_LIKELY(poolId < ExecutorsCount)) {
- return Executors[poolId]->GetDefaultThreadCount();
- } else {
- return {};
- }
- } else {
- return CpuManager.GetThreadsOptional(poolId);
- }
- }
- };
-
- class TActorSystem : TNonCopyable {
- struct TServiceMap;
-
- public:
- const ui32 NodeId;
-
- private:
- THolder<TCpuManager> CpuManager;
- const ui32 ExecutorPoolCount;
-
- TAutoPtr<ISchedulerThread> Scheduler;
- THolder<TServiceMap> ServiceMap;
-
- const ui32 InterconnectCount;
- TArrayHolder<TActorId> Interconnect;
-
- volatile ui64 CurrentTimestamp;
- volatile ui64 CurrentMonotonic;
- volatile ui64 CurrentIDCounter;
-
- THolder<NSchedulerQueue::TQueueType> ScheduleQueue;
- mutable TTicketLock ScheduleLock;
-
- friend class TExecutorThread;
-
- THolder<TActorSystemSetup> SystemSetup;
- TActorId DefSelfID;
- void* AppData0;
- TIntrusivePtr<NLog::TSettings> LoggerSettings0;
- TProxyWrapperFactory ProxyWrapperFactory;
- TMutex ProxyCreationLock;
-
- bool StartExecuted;
- bool StopExecuted;
- bool CleanupExecuted;
-
- std::deque<std::function<void()>> DeferredPreStop;
- public:
- TActorSystem(THolder<TActorSystemSetup>& setup, void* appData = nullptr,
- TIntrusivePtr<NLog::TSettings> loggerSettings = TIntrusivePtr<NLog::TSettings>(nullptr));
- ~TActorSystem();
-
- void Start();
- void Stop();
- void Cleanup();
-
- template <ESendingType SendingType = ESendingType::Common>
- TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 executorPool = 0,
- ui64 revolvingCounter = 0, const TActorId& parentId = TActorId());
-
- bool MonitorStuckActors() const { return SystemSetup->MonitorStuckActors; }
-
- private:
- typedef bool (IExecutorPool::*TEPSendFunction)(TAutoPtr<IEventHandle>& ev);
-
- template <TEPSendFunction EPSpecificSend>
- bool GenericSend(TAutoPtr<IEventHandle> ev) const;
-
- public:
- template <ESendingType SendingType = ESendingType::Common>
- bool Send(TAutoPtr<IEventHandle> ev) const;
-
- bool SpecificSend(TAutoPtr<IEventHandle> ev, ESendingType sendingType) const;
- bool SpecificSend(TAutoPtr<IEventHandle> ev) const;
-
- bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0) const;
-
- /**
- * Schedule one-shot event that will be send at given time point in the future.
- *
- * @param deadline the wallclock time point in future when event must be send
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) const;
-
- /**
- * Schedule one-shot event that will be send at given time point in the future.
- *
- * @param deadline the monotonic time point in future when event must be send
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) const;
-
- /**
- * Schedule one-shot event that will be send after given delay.
- *
- * @param delta the time from now to delay event sending
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- */
- void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) const;
-
- /**
- * A way to interact with actors from non-actor context.
- *
- * This method will send the `event` to the `recipient` and then will wait for a response. When response arrives,
- * it will be passed to the future. If response is not of type `T`, the future will resolve into an exception.
- *
- * @tparam T expected response type. Must be derived from `TEventBase`,
- * or use `IEventBase` to catch any response.
- * @param actorSystem actor system that will be used to register an actor that'll wait for response.
- * @param recipient who will get a request.
- * @param event a request message.
- * @return future that will be resolved when a message from `recipient` arrives.
- */
- template <typename T>
- [[nodiscard]]
- NThreading::TFuture<THolder<T>> Ask(TActorId recipient, THolder<IEventBase> event, TDuration timeout = TDuration::Max()) {
- if constexpr (std::is_same_v<T, IEventBase>) {
- return AskGeneric(Nothing(), recipient, std::move(event), timeout);
- } else {
- return AskGeneric(T::EventType, recipient, std::move(event), timeout)
- .Apply([](const NThreading::TFuture<THolder<IEventBase>>& ev) {
- return THolder<T>(static_cast<T*>(const_cast<THolder<IEventBase>&>(ev.GetValueSync()).Release())); // =(
- });
- }
- }
-
- [[nodiscard]]
- NThreading::TFuture<THolder<IEventBase>> AskGeneric(
- TMaybe<ui32> expectedEventType,
- TActorId recipient,
- THolder<IEventBase> event,
- TDuration timeout);
-
- ui64 AllocateIDSpace(ui64 count);
-
- TActorId InterconnectProxy(ui32 destinationNode) const;
- ui32 BroadcastToProxies(const std::function<IEventHandle*(const TActorId&)>&);
-
- void UpdateLinkStatus(ui8 status, ui32 destinationNode);
- ui8 LinkStatus(ui32 destinationNode);
-
- TActorId LookupLocalService(const TActorId& x) const;
- TActorId RegisterLocalService(const TActorId& serviceId, const TActorId& actorId);
-
- TInstant Timestamp() const {
- return TInstant::MicroSeconds(RelaxedLoad(&CurrentTimestamp));
- }
-
- TMonotonic Monotonic() const {
- return TMonotonic::MicroSeconds(RelaxedLoad(&CurrentMonotonic));
- }
-
- template <typename T>
- T* AppData() const {
- return (T*)AppData0;
- }
-
- NLog::TSettings* LoggerSettings() const {
- return LoggerSettings0.Get();
- }
-
- void GetPoolStats(ui32 poolId, TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const;
-
- THarmonizerStats GetHarmonizerStats() const;
-
- std::optional<ui32> GetPoolThreadsCount(const ui32 poolId) const {
- if (!SystemSetup) {
- return {};
- }
- return SystemSetup->GetThreadsOptional(poolId);
- }
-
- void DeferPreStop(std::function<void()> fn) {
- DeferredPreStop.push_back(std::move(fn));
- }
-
- TVector<IExecutorPool*> GetBasicExecutorPools() const {
- return CpuManager->GetBasicExecutorPools();
- }
-
- };
-}
diff --git a/library/cpp/actors/core/actorsystem_ut.cpp b/library/cpp/actors/core/actorsystem_ut.cpp
deleted file mode 100644
index 231d6f0ca1..0000000000
--- a/library/cpp/actors/core/actorsystem_ut.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "actorsystem.h"
-
-#include <library/cpp/actors/testlib/test_runtime.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NActors;
-
-Y_UNIT_TEST_SUITE(TActorSystemTest) {
-
- class TTestActor: public TActor<TTestActor> {
- public:
- TTestActor()
- : TActor{&TThis::Main}
- {
- }
-
- STATEFN(Main) {
- Y_UNUSED(ev);
- }
- };
-
- THolder<TTestActorRuntimeBase> CreateRuntime() {
- auto runtime = MakeHolder<TTestActorRuntimeBase>();
- runtime->SetScheduledEventFilter([](auto&&, auto&&, auto&&, auto&&) { return false; });
- runtime->Initialize();
- return runtime;
- }
-
- Y_UNIT_TEST(LocalService) {
- THolder<TTestActorRuntimeBase> runtime = CreateRuntime();
- auto actorA = runtime->Register(new TTestActor);
- auto actorB = runtime->Register(new TTestActor);
-
- TActorId myServiceId{0, TStringBuf{"my-service"}};
-
- auto prevActorId = runtime->RegisterService(myServiceId, actorA);
- UNIT_ASSERT(!prevActorId);
- UNIT_ASSERT_EQUAL(runtime->GetLocalServiceId(myServiceId), actorA);
-
- prevActorId = runtime->RegisterService(myServiceId, actorB);
- UNIT_ASSERT(prevActorId);
- UNIT_ASSERT_EQUAL(prevActorId, actorA);
- UNIT_ASSERT_EQUAL(runtime->GetLocalServiceId(myServiceId), actorB);
- }
-}
diff --git a/library/cpp/actors/core/ask.cpp b/library/cpp/actors/core/ask.cpp
deleted file mode 100644
index 40c6748d56..0000000000
--- a/library/cpp/actors/core/ask.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "ask.h"
-
-#include "actor_bootstrapped.h"
-#include "actorid.h"
-#include "event.h"
-#include "hfunc.h"
-
-namespace NActors {
- namespace {
- class TAskActor: public TActorBootstrapped<TAskActor> {
- enum {
- Timeout = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
-
- // We can't use the standard timeout event because recipient may send us one.
- struct TTimeout: public TEventLocal<TTimeout, Timeout> {
- };
-
- public:
- TAskActor(
- TMaybe<ui32> expectedEventType,
- TActorId recipient,
- THolder<IEventBase> event,
- TDuration timeout,
- const NThreading::TPromise<THolder<IEventBase>>& promise)
- : ExpectedEventType_(expectedEventType)
- , Recipient_(recipient)
- , Event_(std::move(event))
- , Timeout_(timeout)
- , Promise_(promise)
- {
- }
-
- static constexpr char ActorName[] = "ASK_ACTOR";
-
- public:
- void Bootstrap() {
- Send(Recipient_, std::move(Event_));
- Become(&TAskActor::Waiting);
-
- if (Timeout_ != TDuration::Max()) {
- Schedule(Timeout_, new TTimeout);
- }
- }
-
- STATEFN(Waiting) {
- if (ev->GetTypeRewrite() == TTimeout::EventType) {
- Promise_.SetException(std::make_exception_ptr(yexception() << "ask timeout"));
- } else if (!ExpectedEventType_ || ev->GetTypeRewrite() == ExpectedEventType_) {
- Promise_.SetValue(ev.Get()->ReleaseBase());
- } else {
- Promise_.SetException(std::make_exception_ptr(yexception() << "received unexpected response " << ev.Get()->GetBase()->ToString()));
- }
-
- PassAway();
- }
-
- public:
- TMaybe<ui32> ExpectedEventType_;
- TActorId Recipient_;
- THolder<IEventBase> Event_;
- TDuration Timeout_;
- NThreading::TPromise<THolder<IEventBase>> Promise_;
- };
- }
-
- THolder<IActor> MakeAskActor(
- TMaybe<ui32> expectedEventType,
- TActorId recipient,
- THolder<IEventBase> event,
- TDuration timeout,
- const NThreading::TPromise<THolder<IEventBase>>& promise)
- {
- return MakeHolder<TAskActor>(expectedEventType, std::move(recipient), std::move(event), timeout, promise);
- }
-}
diff --git a/library/cpp/actors/core/ask.h b/library/cpp/actors/core/ask.h
deleted file mode 100644
index 036f1833a4..0000000000
--- a/library/cpp/actors/core/ask.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include "actor.h"
-#include "event.h"
-
-#include <library/cpp/threading/future/future.h>
-
-namespace NActors {
- /**
- * See `TActorSystem::Ask`.
- */
- THolder<IActor> MakeAskActor(
- TMaybe<ui32> expectedEventType,
- TActorId recipient,
- THolder<IEventBase> event,
- TDuration timeout,
- const NThreading::TPromise<THolder<IEventBase>>& promise);
-}
diff --git a/library/cpp/actors/core/ask_ut.cpp b/library/cpp/actors/core/ask_ut.cpp
deleted file mode 100644
index e72ebdba9b..0000000000
--- a/library/cpp/actors/core/ask_ut.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-#include <library/cpp/testing/unittest/registar.h>
-
-#include "actorsystem.h"
-
-#include <library/cpp/actors/testlib/test_runtime.h>
-
-using namespace NActors;
-
-class TPingPong: public TActor<TPingPong> {
-public:
- TPingPong()
- : TActor(&TPingPong::Main)
- {
- }
-
- STATEFN(Main) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvents::TEvPing, OnPing);
- hFunc(TEvents::TEvBlob, OnBlob);
- }
- }
-
- void OnPing(const TEvents::TEvPing::TPtr& ev) {
- Send(ev->Sender, new TEvents::TEvPong);
- }
-
- void OnBlob(const TEvents::TEvBlob::TPtr& ev) {
- Send(ev->Sender, ev->Release().Release());
- }
-};
-
-class TPing: public TActor<TPing> {
-public:
- TPing()
- : TActor(&TPing::Main)
- {
- }
-
- STATEFN(Main) {
- Y_UNUSED(ev);
- }
-};
-
-THolder<TTestActorRuntimeBase> CreateRuntime() {
- auto runtime = MakeHolder<TTestActorRuntimeBase>();
- runtime->SetScheduledEventFilter([](auto&&, auto&&, auto&&, auto&&) { return false; });
- runtime->Initialize();
- return runtime;
-}
-
-Y_UNIT_TEST_SUITE(AskActor) {
- Y_UNIT_TEST(Ok) {
- auto runtime = CreateRuntime();
- auto pingpong = runtime->Register(new TPingPong);
-
- {
- auto fut = runtime->GetAnyNodeActorSystem()->Ask<TEvents::TEvPong>(
- pingpong,
- THolder(new TEvents::TEvPing));
- runtime->DispatchEvents();
- fut.ExtractValueSync();
- }
-
- {
- auto fut = runtime->GetAnyNodeActorSystem()->Ask<TEvents::TEvBlob>(
- pingpong,
- THolder(new TEvents::TEvBlob("hello!")));
- runtime->DispatchEvents();
- auto ev = fut.ExtractValueSync();
- UNIT_ASSERT_VALUES_EQUAL(ev->Blob, "hello!");
- }
-
- {
- auto fut = runtime->GetAnyNodeActorSystem()->Ask<IEventBase>(
- pingpong,
- THolder(new TEvents::TEvPing));
- runtime->DispatchEvents();
- auto ev = fut.ExtractValueSync();
- UNIT_ASSERT_VALUES_EQUAL(ev->Type(), TEvents::TEvPong::EventType);
- }
- }
-
- Y_UNIT_TEST(Err) {
- auto runtime = CreateRuntime();
- auto pingpong = runtime->Register(new TPingPong);
-
- {
- auto fut = runtime->GetAnyNodeActorSystem()->Ask<TEvents::TEvBlob>(
- pingpong,
- THolder(new TEvents::TEvPing));
- runtime->DispatchEvents();
- UNIT_ASSERT_EXCEPTION_CONTAINS(
- fut.ExtractValueSync(),
- yexception,
- "received unexpected response HelloWorld: Pong");
- }
- }
-
- Y_UNIT_TEST(Timeout) {
- auto runtime = CreateRuntime();
- auto ping = runtime->Register(new TPing);
-
- {
- auto fut = runtime->GetAnyNodeActorSystem()->Ask<TEvents::TEvPong>(
- ping,
- THolder(new TEvents::TEvPing),
- TDuration::Seconds(1));
- auto start = runtime->GetCurrentTime();
- runtime->DispatchEvents({}, TDuration::Seconds(5));
- UNIT_ASSERT_EXCEPTION_CONTAINS(
- fut.ExtractValueSync(),
- yexception,
- "ask timeout");
- UNIT_ASSERT_VALUES_EQUAL(runtime->GetCurrentTime() - start, TDuration::Seconds(1));
- }
-
- {
- auto fut = runtime->GetAnyNodeActorSystem()->Ask<IEventBase>(
- ping,
- THolder(new TEvents::TEvPing),
- TDuration::Seconds(1));
- auto start = runtime->GetCurrentTime();
- runtime->DispatchEvents({}, TDuration::Seconds(5));
- UNIT_ASSERT_EXCEPTION_CONTAINS(
- fut.ExtractValueSync(),
- yexception,
- "ask timeout");
- UNIT_ASSERT_VALUES_EQUAL(runtime->GetCurrentTime() - start, TDuration::Seconds(1));
- }
- }
-}
diff --git a/library/cpp/actors/core/av_bootstrapped.cpp b/library/cpp/actors/core/av_bootstrapped.cpp
deleted file mode 100644
index 771177242e..0000000000
--- a/library/cpp/actors/core/av_bootstrapped.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "av_bootstrapped.h"
-
-namespace NActors {
-
-class TEventForStart: public TEventLocalForActor<TEventForStart, TActorAutoStart> {
-public:
-};
-
-TAutoPtr<NActors::IEventHandle> TActorAutoStart::AfterRegister(const TActorId& self, const TActorId& parentId) {
- return new IEventHandle(self, parentId, new TEventForStart, 0);
-}
-
-void TActorAutoStart::ProcessEvent(TEventContext<TEventForStart>& ev) {
- DoOnStart(ev.GetHandle().Sender);
-}
-
-}
diff --git a/library/cpp/actors/core/av_bootstrapped.h b/library/cpp/actors/core/av_bootstrapped.h
deleted file mode 100644
index 65bd224152..0000000000
--- a/library/cpp/actors/core/av_bootstrapped.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-#include "actor_virtual.h"
-
-namespace NActors {
-
-class TEventForStart;
-
-class TActorAutoStart: public IActor {
-protected:
- virtual void DoOnStart(const TActorId& senderActorId) = 0;
- TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) override;
-public:
- void ProcessEvent(TEventContext<TEventForStart>& ev);
-
- TActorAutoStart()
- {}
-};
-}
diff --git a/library/cpp/actors/core/balancer.cpp b/library/cpp/actors/core/balancer.cpp
deleted file mode 100644
index 5e8a280a8b..0000000000
--- a/library/cpp/actors/core/balancer.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-#include "balancer.h"
-
-#include "probes.h"
-
-#include <library/cpp/actors/util/cpu_load_log.h>
-#include <library/cpp/actors/util/datetime.h>
-#include <library/cpp/actors/util/intrinsics.h>
-
-#include <util/system/spinlock.h>
-
-#include <algorithm>
-
-namespace NActors {
- LWTRACE_USING(ACTORLIB_PROVIDER);
-
- // Describes balancing-related state of pool, the most notable is `Importance` to add new cpu
- struct TLevel {
- // Balancer will try to give more cpu to overloaded pools
- enum ELoadClass {
- Underloaded = 0,
- Moderate = 1,
- Overloaded = 2,
- };
-
- double ScaleFactor;
- ELoadClass LoadClass;
- ui64 Importance; // pool with lower importance is allowed to pass cpu to pool with higher, but the opposite is forbidden
-
- TLevel() {}
-
- TLevel(const TBalancingConfig& cfg, TPoolId poolId, ui64 currentCpus, double cpuIdle, ui64 addLatencyUs, ui64 worstLatencyUs) {
- ScaleFactor = double(currentCpus) / cfg.Cpus;
- if ((worstLatencyUs + addLatencyUs) < 2000 && cpuIdle > 1.0) { // Uderload criterion, based on estimated latency w/o 1 cpu
- LoadClass = Underloaded;
- } else if (worstLatencyUs > 2000 || cpuIdle < 0.2) { // Overload criterion, based on latency
- LoadClass = Overloaded;
- } else {
- LoadClass = Moderate;
- }
- Importance = MakeImportance(LoadClass, cfg.Priority, ScaleFactor, cpuIdle, poolId);
- }
-
- private:
- // Importance is simple ui64 value (from highest to lowest):
- // 2 Bits: LoadClass
- // 8 Bits: Priority
- // 10 Bits: -ScaleFactor (for max-min fairness with weights equal to TBalancingConfig::Cpus)
- // 10 Bits: -CpuIdle
- // 6 Bits: PoolId
- static ui64 MakeImportance(ELoadClass load, ui8 priority, double scaleFactor, double cpuIdle, TPoolId poolId) {
- ui64 idle = std::clamp<i64>(1024 - cpuIdle * 512, 0, 1023);
- ui64 scale = std::clamp<i64>(1024 - scaleFactor * 32, 0, 1023);
-
- Y_ABORT_UNLESS(ui64(load) < (1ull << 2ull));
- Y_ABORT_UNLESS(ui64(priority) < (1ull << 8ull));
- Y_ABORT_UNLESS(ui64(scale) < (1ull << 10ull));
- Y_ABORT_UNLESS(ui64(idle) < (1ull << 10ull));
- Y_ABORT_UNLESS(ui64(poolId) < (1ull << 6ull));
-
- static_assert(ui64(MaxPools) <= (1ull << 6ull));
-
- ui64 importance =
- (ui64(load) << ui64(6 + 10 + 10 + 8)) |
- (ui64(priority) << ui64(6 + 10 + 10)) |
- (ui64(scale) << ui64(6 + 10)) |
- (ui64(idle) << ui64(6)) |
- ui64(poolId);
- return importance;
- }
- };
-
- // Main balancer implemenation
- class TBalancer: public IBalancer {
- private:
- struct TCpu;
- struct TPool;
-
- bool Disabled = true;
- TSpinLock Lock;
- ui64 NextBalanceTs;
- TVector<TCpu> Cpus; // Indexed by CpuId, can have gaps
- TVector<TPool> Pools; // Indexed by PoolId, can have gaps
- TBalancerConfig Config;
-
- public:
-
- ui64 GetPeriodUs() override;
- // Setup
- TBalancer(const TBalancerConfig& config, const TVector<TUnitedExecutorPoolConfig>& unitedPools, ui64 ts);
- bool AddCpu(const TCpuAllocation& cpuAlloc, TCpuState* cpu) override;
- ~TBalancer();
-
- // Balancing
- bool TryLock(ui64 ts) override;
- void SetPoolStats(TPoolId pool, const TBalancerStats& stats) override;
- void Balance() override;
- void Unlock() override;
-
- private:
- void MoveCpu(TPool& from, TPool& to);
- };
-
- struct TBalancer::TPool {
- TBalancingConfig Config;
- TPoolId PoolId;
- TString PoolName;
-
- // Input data for balancing
- TBalancerStats Prev;
- TBalancerStats Next;
-
- // Derived stats
- double CpuLoad;
- double CpuIdle;
-
- // Classification
- // NOTE: We want to avoid passing cpu back and forth, so we must consider not only current level,
- // NOTE: but expected levels after movements also
- TLevel CurLevel; // Level with current amount of cpu
- TLevel AddLevel; // Level after one cpu acception
- TLevel SubLevel; // Level after one cpu donation
-
- // Balancing state
- ui64 CurrentCpus = 0; // Total number of cpus assigned for this pool (zero means pools is not balanced)
- ui64 PrevCpus = 0; // Cpus in last period
-
- explicit TPool(const TBalancingConfig& cfg = {})
- : Config(cfg)
- {}
-
- void Configure(const TBalancingConfig& cfg, const TString& poolName) {
- Config = cfg;
- // Enforce constraints
- if (Config.Cpus > 0) {
- Config.MinCpus = std::clamp<ui32>(Config.MinCpus, 1, Config.Cpus);
- Config.MaxCpus = Max<ui32>(Config.MaxCpus, Config.Cpus);
- } else {
- Y_ABORT_UNLESS(Config.Cpus == 0,
- "Unexpected negative Config.Cpus# %" PRIi64,
- (i64)Config.Cpus);
- Config.MinCpus = 0;
- Config.MaxCpus = 0;
- }
- PoolName = poolName;
- }
- };
-
- struct TBalancer::TCpu {
- TCpuState* State = nullptr; // Cpu state, nullptr means cpu is not used (gap)
- TCpuAllocation Alloc;
- TPoolId Current;
- TPoolId Assigned;
- };
-
- TBalancer::TBalancer(const TBalancerConfig& config, const TVector<TUnitedExecutorPoolConfig>& unitedPools, ui64 ts)
- : NextBalanceTs(ts)
- , Config(config)
- {
- for (TPoolId pool = 0; pool < MaxPools; pool++) {
- Pools.emplace_back();
- Pools.back().PoolId = pool;
- }
- for (const TUnitedExecutorPoolConfig& united : unitedPools) {
- Pools[united.PoolId].Configure(united.Balancing, united.PoolName);
- }
- }
-
- TBalancer::~TBalancer() {
- }
-
- bool TBalancer::AddCpu(const TCpuAllocation& cpuAlloc, TCpuState* state) {
- // Setup
- TCpuId cpuId = cpuAlloc.CpuId;
- if (Cpus.size() <= cpuId) {
- Cpus.resize(cpuId + 1);
- }
- TCpu& cpu = Cpus[cpuId];
- cpu.State = state;
- cpu.Alloc = cpuAlloc;
-
- // Fill every pool with cpus up to TBalancingConfig::Cpus
- TPoolId pool = 0;
- for (TPool& p : Pools) {
- if (p.CurrentCpus < p.Config.Cpus) {
- p.CurrentCpus++;
- break;
- }
- pool++;
- }
- if (pool != MaxPools) { // cpu under balancer control
- state->SwitchPool(pool);
- state->AssignPool(pool);
- Disabled = false;
- return true;
- }
- return false; // non-balanced cpu
- }
-
- bool TBalancer::TryLock(ui64 ts) {
- if (!Disabled && NextBalanceTs < ts && Lock.TryAcquire()) {
- NextBalanceTs = ts + Us2Ts(Config.PeriodUs);
- return true;
- }
- return false;
- }
-
- void TBalancer::SetPoolStats(TPoolId pool, const TBalancerStats& stats) {
- Y_ABORT_UNLESS(pool < MaxPools);
- TPool& p = Pools[pool];
- p.Prev = p.Next;
- p.Next = stats;
- }
-
- void TBalancer::Balance() {
- // Update every cpu state
- for (TCpu& cpu : Cpus) {
- if (cpu.State) {
- cpu.State->Load(cpu.Assigned, cpu.Current);
- if (cpu.Current < MaxPools && cpu.Current != cpu.Assigned) {
- return; // previous movement has not been applied yet, wait
- }
- }
- }
-
- // Process stats, classify and compute pool importance
- TStackVec<TPool*, MaxPools> order;
- for (TPool& pool : Pools) {
- if (pool.Config.Cpus == 0) {
- continue; // skip gaps (non-existent or non-united pools)
- }
- if (pool.Prev.Ts == 0 || pool.Prev.Ts >= pool.Next.Ts) {
- return; // invalid stats
- }
-
- // Compute derived stats
- pool.CpuLoad = (pool.Next.CpuUs - pool.Prev.CpuUs) / Ts2Us(pool.Next.Ts - pool.Prev.Ts);
- if (pool.Prev.IdleUs == ui64(-1) || pool.Next.IdleUs == ui64(-1)) {
- pool.CpuIdle = pool.CurrentCpus - pool.CpuLoad; // for tests
- } else {
- pool.CpuIdle = (pool.Next.IdleUs - pool.Prev.IdleUs) / Ts2Us(pool.Next.Ts - pool.Prev.Ts);
- }
-
- // Compute levels
- pool.CurLevel = TLevel(pool.Config, pool.PoolId, pool.CurrentCpus, pool.CpuIdle,
- pool.Next.ExpectedLatencyIncreaseUs, pool.Next.WorstActivationTimeUs);
- pool.AddLevel = TLevel(pool.Config, pool.PoolId, pool.CurrentCpus + 1, pool.CpuIdle,
- 0, pool.Next.WorstActivationTimeUs); // we expect taken cpu to became utilized
- pool.SubLevel = TLevel(pool.Config, pool.PoolId, pool.CurrentCpus - 1, pool.CpuIdle - 1,
- pool.Next.ExpectedLatencyIncreaseUs, pool.Next.WorstActivationTimeUs);
-
- // Prepare for balancing
- pool.PrevCpus = pool.CurrentCpus;
- order.push_back(&pool);
- }
-
- // Sort pools by importance
- std::sort(order.begin(), order.end(), [] (TPool* l, TPool* r) {return l->CurLevel.Importance < r->CurLevel.Importance; });
- for (TPool* pool : order) {
- LWPROBE(PoolStats, pool->PoolId, pool->PoolName, pool->CurrentCpus, pool->CurLevel.LoadClass, pool->Config.Priority, pool->CurLevel.ScaleFactor, pool->CpuIdle, pool->CpuLoad, pool->CurLevel.Importance, pool->AddLevel.Importance, pool->SubLevel.Importance);
- }
-
- // Move cpus from lower importance to higher importance pools
- for (auto toIter = order.rbegin(); toIter != order.rend(); ++toIter) {
- TPool& to = **toIter;
- if (to.CurLevel.LoadClass == TLevel::Overloaded && // if pool is overloaded
- to.CurrentCpus < to.Config.MaxCpus) // and constraints would not be violated
- {
- for (auto fromIter = order.begin(); (*fromIter)->CurLevel.Importance < to.CurLevel.Importance; ++fromIter) {
- TPool& from = **fromIter;
- if (from.CurrentCpus == from.PrevCpus && // if not balanced yet
- from.CurrentCpus > from.Config.MinCpus && // and constraints would not be violated
- from.SubLevel.Importance <= to.AddLevel.Importance) // and which of two pools is more important would not change after cpu movement
- {
- MoveCpu(from, to);
- from.CurrentCpus--;
- to.CurrentCpus++;
- break;
- }
- }
- }
- }
- }
-
- void TBalancer::MoveCpu(TBalancer::TPool& from, TBalancer::TPool& to) {
- for (auto ci = Cpus.rbegin(), ce = Cpus.rend(); ci != ce; ci++) {
- TCpu& cpu = *ci;
- if (!cpu.State) {
- continue;
- }
- if (cpu.Assigned == from.PoolId) {
- cpu.State->AssignPool(to.PoolId);
- cpu.Assigned = to.PoolId;
- LWPROBE(MoveCpu, from.PoolId, to.PoolId, from.PoolName, to.PoolName, cpu.Alloc.CpuId);
- return;
- }
- }
- Y_ABORT();
- }
-
- void TBalancer::Unlock() {
- Lock.Release();
- }
-
- ui64 TBalancer::GetPeriodUs() {
- return Config.PeriodUs;
- }
-
- IBalancer* MakeBalancer(const TBalancerConfig& config, const TVector<TUnitedExecutorPoolConfig>& unitedPools, ui64 ts) {
- return new TBalancer(config, unitedPools, ts);
- }
-}
diff --git a/library/cpp/actors/core/balancer.h b/library/cpp/actors/core/balancer.h
deleted file mode 100644
index e1f6f33bf3..0000000000
--- a/library/cpp/actors/core/balancer.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include "config.h"
-#include "cpu_state.h"
-
-namespace NActors {
- // Per-pool statistics used by balancer
- struct TBalancerStats {
- ui64 Ts = 0; // Measurement timestamp
- ui64 CpuUs = 0; // Total cpu microseconds consumed by pool on all cpus since start
- ui64 IdleUs = ui64(-1); // Total cpu microseconds in spinning or waiting on futex
- ui64 WorstActivationTimeUs = 0;
- ui64 ExpectedLatencyIncreaseUs = 0;
- };
-
- // Pool cpu balancer
- struct IBalancer {
- virtual ~IBalancer() {}
- virtual bool AddCpu(const TCpuAllocation& cpuAlloc, TCpuState* cpu) = 0;
- virtual bool TryLock(ui64 ts) = 0;
- virtual void SetPoolStats(TPoolId pool, const TBalancerStats& stats) = 0;
- virtual void Balance() = 0;
- virtual void Unlock() = 0;
- virtual ui64 GetPeriodUs() = 0;
- // TODO: add method for reconfiguration on fly
- };
-
- IBalancer* MakeBalancer(const TBalancerConfig& config, const TVector<TUnitedExecutorPoolConfig>& unitedPools, ui64 ts);
-}
diff --git a/library/cpp/actors/core/balancer_ut.cpp b/library/cpp/actors/core/balancer_ut.cpp
deleted file mode 100644
index 7e5e95f4b9..0000000000
--- a/library/cpp/actors/core/balancer_ut.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-#include "balancer.h"
-
-#include <library/cpp/actors/util/datetime.h>
-#include <library/cpp/lwtrace/all.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/stream/str.h>
-
-using namespace NActors;
-
-////////////////////////////////////////////////////////////////////////////////
-
-Y_UNIT_TEST_SUITE(PoolCpuBalancer) {
- struct TTest {
- TCpuManagerConfig Config;
- TCpuMask Available;
- THolder<IBalancer> Balancer;
- TVector<TCpuState> CpuStates;
- TVector<ui64> CpuUs;
- ui64 Now = 0;
-
- void SetCpuCount(size_t count) {
- Config.UnitedWorkers.CpuCount = count;
- for (TCpuId cpuId = 0; cpuId < count; cpuId++) {
- Available.Set(cpuId);
- }
- }
-
- void AddPool(ui32 minCpus, ui32 cpus, ui32 maxCpus, ui8 priority = 0) {
- TUnitedExecutorPoolConfig u;
- u.PoolId = TPoolId(Config.United.size());
- u.Balancing.Cpus = cpus;
- u.Balancing.MinCpus = minCpus;
- u.Balancing.MaxCpus = maxCpus;
- u.Balancing.Priority = priority;
- Config.United.push_back(u);
- }
-
- void Start() {
- TCpuAllocationConfig allocation(Available, Config);
- Balancer.Reset(MakeBalancer(Config.UnitedWorkers.Balancer, Config.United, 0));
- CpuStates.resize(allocation.Items.size()); // do not resize it later to avoid dangling pointers
- CpuUs.resize(CpuStates.size());
- for (const TCpuAllocation& cpuAlloc : allocation.Items) {
- bool added = Balancer->AddCpu(cpuAlloc, &CpuStates[cpuAlloc.CpuId]);
- UNIT_ASSERT(added);
- }
- }
-
- void Balance(ui64 deltaTs, const TVector<ui64>& cpuUs) {
- Now += deltaTs;
- ui64 ts = Now;
- if (Balancer->TryLock(ts)) {
- for (TPoolId pool = 0; pool < cpuUs.size(); pool++) {
- CpuUs[pool] += cpuUs[pool];
- TBalancerStats stats;
- stats.Ts = ts;
- stats.CpuUs = CpuUs[pool];
- Balancer->SetPoolStats(pool, stats);
- }
- Balancer->Balance();
- Balancer->Unlock();
- }
- }
-
- void ApplyMovements() {
- for (TCpuState& state : CpuStates) {
- TPoolId current;
- TPoolId assigned;
- state.Load(assigned, current);
- state.SwitchPool(assigned);
- }
- }
-
- static TString ToStr(const TVector<ui64>& values) {
- TStringStream ss;
- ss << "{";
- for (auto v : values) {
- ss << " " << v;
- }
- ss << " }";
- return ss.Str();
- }
-
- void AssertPoolsCurrentCpus(const TVector<ui64>& cpuRequired) {
- TVector<ui64> cpuCurrent;
- cpuCurrent.resize(cpuRequired.size());
- for (TCpuState& state : CpuStates) {
- TPoolId current;
- TPoolId assigned;
- state.Load(assigned, current);
- cpuCurrent[current]++;
- }
- for (TPoolId pool = 0; pool < cpuRequired.size(); pool++) {
- UNIT_ASSERT_C(cpuCurrent[pool] == cpuRequired[pool],
- "cpu distribution mismatch, required " << ToStr(cpuRequired) << " but got " << ToStr(cpuCurrent));
- }
- }
- };
-
- Y_UNIT_TEST(StartLwtrace) {
- NLWTrace::StartLwtraceFromEnv();
- }
-
- Y_UNIT_TEST(AllOverloaded) {
- TTest t;
- int cpus = 10;
- t.SetCpuCount(cpus);
- t.AddPool(1, 1, 10); // pool=0
- t.AddPool(1, 2, 10); // pool=1
- t.AddPool(1, 3, 10); // pool=2
- t.AddPool(1, 4, 10); // pool=2
- t.Start();
- ui64 dts = 1.01 * Us2Ts(t.Config.UnitedWorkers.Balancer.PeriodUs);
- ui64 totalCpuUs = cpus * Ts2Us(dts); // pretend every pool has consumed as whole actorsystem, overload
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {totalCpuUs, totalCpuUs, totalCpuUs, totalCpuUs});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({1, 2, 3, 4});
- }
-
- Y_UNIT_TEST(OneOverloaded) {
- TTest t;
- int cpus = 10;
- t.SetCpuCount(cpus);
- t.AddPool(1, 1, 10); // pool=0
- t.AddPool(1, 2, 10); // pool=1
- t.AddPool(1, 3, 10); // pool=2
- t.AddPool(1, 4, 10); // pool=2
- t.Start();
- ui64 dts = 1.01 * Us2Ts(t.Config.UnitedWorkers.Balancer.PeriodUs);
- ui64 totalCpuUs = cpus * Ts2Us(dts);
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {totalCpuUs, 0, 0, 0});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({7, 1, 1, 1});
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {0, totalCpuUs, 0, 0});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({1, 7, 1, 1});
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {0, 0, totalCpuUs, 0});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({1, 1, 7, 1});
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {0, 0, 0, totalCpuUs});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({1, 1, 1, 7});
- }
-
- Y_UNIT_TEST(TwoOverloadedFairness) {
- TTest t;
- int cpus = 10;
- t.SetCpuCount(cpus);
- t.AddPool(1, 1, 10); // pool=0
- t.AddPool(1, 2, 10); // pool=1
- t.AddPool(1, 3, 10); // pool=2
- t.AddPool(1, 4, 10); // pool=2
- t.Start();
- ui64 dts = 1.01 * Us2Ts(t.Config.UnitedWorkers.Balancer.PeriodUs);
- ui64 totalCpuUs = cpus * Ts2Us(dts);
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {totalCpuUs, totalCpuUs, 0, 0});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({3, 5, 1, 1});
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {totalCpuUs, 0, totalCpuUs, 0});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({2, 1, 6, 1});
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {totalCpuUs, 0, 0, totalCpuUs});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({2, 1, 1, 6});
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {0, totalCpuUs, totalCpuUs, 0});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({1, 3, 5, 1});
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {0, totalCpuUs, 0, totalCpuUs});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({1, 3, 1, 5});
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {0, 0, totalCpuUs, totalCpuUs});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({1, 1, 3, 5});
- }
-
- Y_UNIT_TEST(TwoOverloadedPriority) {
- TTest t;
- int cpus = 20;
- t.SetCpuCount(cpus);
- t.AddPool(1, 5, 20, 0); // pool=0
- t.AddPool(1, 5, 20, 1); // pool=1
- t.AddPool(1, 5, 20, 2); // pool=2
- t.AddPool(1, 5, 20, 3); // pool=3
- t.Start();
- ui64 dts = 1.01 * Us2Ts(t.Config.UnitedWorkers.Balancer.PeriodUs);
- ui64 mErlang = Ts2Us(dts) / 1000;
- for (int i = 0; i < cpus; i++) {
- t.Balance(dts, {20000 * mErlang, 2500 * mErlang, 4500 * mErlang, 9500 * mErlang});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({2, 3, 5, 10});
- t.Balance(dts, {20000 * mErlang, 2500 * mErlang, 4500 * mErlang, 8500 * mErlang});
- t.ApplyMovements();
- t.AssertPoolsCurrentCpus({3, 3, 5, 9});
- // NOTE: this operation require one move, but we do not make global analysis, so multiple steps (1->2 & 0->1) are required (can be optimized later)
- for (int i = 0; i < 3; i++) {
- t.Balance(dts, {20000 * mErlang, 2500 * mErlang, 5500 * mErlang, 8500 * mErlang});
- t.ApplyMovements();
- }
- t.AssertPoolsCurrentCpus({2, 3, 6, 9});
- }
-}
diff --git a/library/cpp/actors/core/benchmark_ut.cpp b/library/cpp/actors/core/benchmark_ut.cpp
deleted file mode 100644
index 380e983b92..0000000000
--- a/library/cpp/actors/core/benchmark_ut.cpp
+++ /dev/null
@@ -1,1111 +0,0 @@
-#include "actorsystem.h"
-#include "actor_bootstrapped.h"
-#include "config.h"
-#include "executor_pool_basic.h"
-#include "hfunc.h"
-#include "scheduler_basic.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/thread/pool.h>
-
-#include <algorithm>
-#include <atomic>
-#include <chrono>
-#include <condition_variable>
-#include <iostream>
-#include <memory>
-#include <mutex>
-#include <optional>
-#include <span>
-#include <string>
-#include <thread>
-#include <utility>
-#include <unordered_set>
-#include <unordered_map>
-#include <vector>
-
-#define BENCH_START(label) auto label##Start = std::chrono::steady_clock::now()
-#define BENCH_END(label) std::chrono::steady_clock::now() - label##Start
-
-using namespace NActors;
-using namespace std::chrono_literals;
-
-Y_UNIT_TEST_SUITE(ActorSystemBenchmark) {
-
- enum ESimpleEventType {
- EvQuickSort,
- EvSumVector,
- EvSumVectorResult,
- EvSumSendRequests,
- EvKvSearch,
- EvKvSendRequests,
- };
-
- using TContainer = std::vector<i32>;
- using TActorIds = std::span<TActorId>;
-
- template <typename TId>
- class TActiveEntityRegistry {
- private:
- std::unordered_set<TId> ActiveIds_;
- std::mutex ActiveIdsMutex_;
- std::condition_variable ActiveIdsCv_;
-
- public:
- void SetActive(TId id) {
- std::unique_lock lock(ActiveIdsMutex_);
- ActiveIds_.insert(std::move(id));
- }
-
- void SetInactive(const TId& id) {
- std::unique_lock lock(ActiveIdsMutex_);
- ActiveIds_.erase(id);
- if (ActiveIds_.empty()) {
- ActiveIdsCv_.notify_all();
- }
- }
-
- bool WaitForAllInactive(std::chrono::microseconds timeout = 1ms) {
- std::unique_lock lock(ActiveIdsMutex_);
- ActiveIdsCv_.wait_for(lock, timeout, [this] {
- return ActiveIds_.empty();
- });
- return ActiveIds_.empty();
- }
- };
-
- class TQuickSortEngine {
- public:
- struct TParameters {
- TContainer &Container;
- i32 Left;
- i32 Right;
- void* CustomData = nullptr;
-
- TParameters() = delete;
- TParameters(TContainer& container, i32 left, i32 right, void* customData)
- : Container(container)
- , Left(left)
- , Right(right)
- , CustomData(customData)
- {}
- };
-
- public:
- void Sort(TQuickSortEngine::TParameters& params) {
- auto [newRight, newLeft] = Partition(params.Container, params.Left, params.Right);
- if (!(params.Left < newRight || newLeft < params.Right)) {
- return;
- }
-
- auto [leftParams, rightParams] = SplitParameters(params, newRight, newLeft);
-
- bool ranAsync = false;
-
- if (newLeft < params.Right) {
- ranAsync = TryRunAsync(rightParams);
- if (ranAsync) {
- Sort(rightParams);
- }
- }
- if (params.Left < newRight) {
- if (!ranAsync && !TryRunAsync(leftParams)) {
- Sort(leftParams);
- }
- }
- }
-
- // returns bounds of left and right sub-arrays for the next iteration
- std::pair<i32, i32> Partition(TContainer& container, i32 left, i32 right) {
- ui32 pivotIndex = (left + right) / 2;
- auto pivot = container[pivotIndex];
- while (left <= right) {
- while (container[left] < pivot) {
- left++;
- }
- while (container[right] > pivot) {
- right--;
- }
-
- if (left <= right) {
- std::swap(container[left++], container[right--]);
- }
- }
- return {right, left};
- }
-
- protected:
- virtual std::pair<TParameters, TParameters> SplitParameters(const TParameters& params, i32 newRight, i32 newLeft) = 0;
- virtual bool TryRunAsync(const TParameters& params) = 0;
- };
-
- class TQuickSortTask : public TQuickSortEngine, public IObjectInQueue {
- public:
- using TParameters = TQuickSortEngine::TParameters;
- struct TThreadPoolParameters {
- const ui32 ThreadsLimit = 0;
- std::atomic<ui32> ThreadsUsed = 0;
- TThreadPool& ThreadPool;
-
- TThreadPoolParameters(ui32 threadsLimit, ui32 threadsUsed, TThreadPool &threadPool)
- : ThreadsLimit(threadsLimit)
- , ThreadsUsed(threadsUsed)
- , ThreadPool(threadPool)
- {}
- };
- TParameters Params;
- TActiveEntityRegistry<TQuickSortTask*>& ActiveThreadRegistry;
-
- public:
- TQuickSortTask() = delete;
- TQuickSortTask(TParameters params, TActiveEntityRegistry<TQuickSortTask*>& activeThreadRegistry)
- : Params(params)
- , ActiveThreadRegistry(activeThreadRegistry)
- {
- ActiveThreadRegistry.SetActive(this);
- }
-
- void Process(void*) override {
- Sort(Params);
- ActiveThreadRegistry.SetInactive(this);
- }
-
- protected:
- std::pair<TParameters, TParameters> SplitParameters(const TParameters& params, i32 newRight, i32 newLeft) override {
- return {
- {params.Container, params.Left, newRight, params.CustomData},
- {params.Container, newLeft, params.Right, params.CustomData}
- };
- }
-
- bool TryRunAsync(const TParameters& params) override {
- auto threadPoolParams = static_cast<TThreadPoolParameters*>(params.CustomData);
- if (threadPoolParams->ThreadsUsed++ >= threadPoolParams->ThreadsLimit) {
- threadPoolParams->ThreadsUsed--;
- return false;
- }
- return threadPoolParams->ThreadPool.AddAndOwn(THolder(new TQuickSortTask(params, ActiveThreadRegistry)));
- }
- };
-
- class TEvQuickSort : public TEventLocal<TEvQuickSort, EvQuickSort> {
- public:
- using TParameters = TQuickSortEngine::TParameters;
- struct TActorSystemParameters {
- TActorIds ActorIds;
- std::atomic<ui32> ActorIdsUsed = 0;
- TActorSystemParameters() = delete;
- TActorSystemParameters(const TActorIds& actorIds, ui32 actorIdsUsed = 0)
- : ActorIds(actorIds)
- , ActorIdsUsed(actorIdsUsed)
- {}
- };
-
- TQuickSortEngine::TParameters Params;
-
- public:
- TEvQuickSort() = delete;
- TEvQuickSort(TParameters params, TActiveEntityRegistry<TEvQuickSort*>& activeEventRegistry)
- : Params(params)
- , ActiveEventRegistry_(activeEventRegistry)
- {
- Y_ABORT_UNLESS(!Params.Container.empty());
- Y_ABORT_UNLESS(Params.Right - Params.Left + 1 <= static_cast<i32>(Params.Container.size()),
- "left: %d, right: %d, cont.size: %d", Params.Left, Params.Right, static_cast<i32>(Params.Container.size()));
- ActiveEventRegistry_.SetActive(this);
- }
-
- virtual ~TEvQuickSort() {
- ActiveEventRegistry_.SetInactive(this);
- }
-
- private:
- TActiveEntityRegistry<TEvQuickSort*>& ActiveEventRegistry_;
- };
-
- class TQuickSortActor : public TQuickSortEngine, public TActorBootstrapped<TQuickSortActor> {
- public:
- using TParameters = TQuickSortEngine::TParameters;
-
- private:
- TActiveEntityRegistry<TEvQuickSort*>& ActiveEventRegistry_;
-
- public:
- TQuickSortActor() = delete;
- TQuickSortActor(TActiveEntityRegistry<TEvQuickSort*>& activeEventRegistry)
- : TActorBootstrapped<TQuickSortActor>()
- , ActiveEventRegistry_(activeEventRegistry)
- {}
-
- STFUNC(StateInit) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvQuickSort, Handle);
- default:
- Y_ABORT_UNLESS(false);
- }
- }
-
- void Bootstrap() {
- Become(&TThis::StateInit);
- }
-
- protected:
- std::pair<TParameters, TParameters> SplitParameters(const TParameters& params, i32 newRight, i32 newLeft) override {
- return {
- {params.Container, params.Left, newRight, params.CustomData},
- {params.Container, newLeft, params.Right, params.CustomData}
- };
- }
-
- bool TryRunAsync(const TParameters& params) override {
- auto actorSystemParams = static_cast<TEvQuickSort::TActorSystemParameters*>(params.CustomData);
- const auto actorIdIndex = actorSystemParams->ActorIdsUsed++;
- if (actorIdIndex >= actorSystemParams->ActorIds.size()) {
- actorSystemParams->ActorIdsUsed--;
- return false;
- }
- auto targetActorId = actorSystemParams->ActorIds[actorIdIndex];
- Send(targetActorId, new TEvQuickSort(params, ActiveEventRegistry_));
- return true;
- }
-
- private:
- void Handle(TEvQuickSort::TPtr& ev) {
- auto evPtr = ev->Get();
- Sort(evPtr->Params);
- }
- };
-
- std::vector<i32> PrepareVectorToSort(ui32 n) {
- std::vector<i32> numbers(n);
- for (ui32 i = 0; i < numbers.size(); i++) {
- numbers[i] = numbers.size() - i;
- }
- return numbers;
- }
-
- std::unique_ptr<TActorSystem> PrepareActorSystem(ui32 poolThreads, TAffinity* affinity = nullptr) {
- auto setup = MakeHolder<TActorSystemSetup>();
- setup->NodeId = 1;
-
- setup->ExecutorsCount = 1;
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[setup->ExecutorsCount]);
-
- ui32 poolId = 0;
- ui64 poolSpinThreashold = 20;
- setup->Executors[0].Reset(new TBasicExecutorPool(
- poolId, poolThreads, poolSpinThreashold, "", nullptr, affinity));
- TSchedulerConfig schedulerConfig;
- schedulerConfig.ResolutionMicroseconds = 512;
- schedulerConfig.SpinThreshold = 100;
- setup->Scheduler.Reset(new TBasicSchedulerThread(schedulerConfig));
-
- return std::make_unique<TActorSystem>(setup);
- }
-
- std::vector<TActorId> prepareQuickSortActors(
- TActorSystem* actorSystem, ui32 actorsNum, TActiveEntityRegistry<TEvQuickSort*>& activeEventRegistry
- ) {
- std::vector<TActorId> actorIds;
- actorIds.reserve(actorsNum);
-
- for (ui32 i = 0; i < actorsNum; i++) {
- auto actor = new TQuickSortActor(activeEventRegistry);
- auto actorId = actorSystem->Register(actor);
- actorIds.push_back(actorId);
- }
-
- return actorIds;
- }
-
- std::pair<std::chrono::microseconds, std::vector<i32>> BenchmarkQuickSortActor(
- ui32 threads,
- ui32 iterations,
- ui32 vectorSize
- ) {
- auto actorSystem = PrepareActorSystem(threads);
- actorSystem->Start();
-
- TActiveEntityRegistry<TEvQuickSort*> activeEventRegistry;
- auto actorIds = prepareQuickSortActors(actorSystem.get(), threads, activeEventRegistry);
-
- std::vector<i32> actorSortResult;
- auto actorQsDurationTotal = 0us;
- for (ui32 i = 0; i < iterations; i++) {
- auto numbers = PrepareVectorToSort(vectorSize);
-
- TEvQuickSort::TActorSystemParameters actorSystemParams(actorIds, 1);
- TEvQuickSort::TParameters params(numbers, 0, numbers.size() - 1, &actorSystemParams);
- auto ev3 = new TEvQuickSort(params, activeEventRegistry);
-
- BENCH_START(qs);
-
- actorSystem->Send(actorIds.front(), ev3);
- UNIT_ASSERT_C(activeEventRegistry.WaitForAllInactive(60s), "timeout");
-
- actorQsDurationTotal += std::chrono::duration_cast<std::chrono::microseconds>(BENCH_END(qs));
-
- if (i + 1 == iterations) {
- actorSortResult = numbers;
- }
- }
-
- return {actorQsDurationTotal / iterations, actorSortResult};
- }
-
- std::pair<std::chrono::microseconds, std::vector<i32>> BenchmarkQuickSortThreadPool(
- ui32 threads,
- ui32 iterations,
- ui32 vectorSize
- ) {
- TThreadPool threadPool;
- threadPool.Start(threads);
- TActiveEntityRegistry<TQuickSortTask*> activeThreadRegistry;
-
- auto threaPoolSortDurationTotal = 0us;
- std::vector<i32> threadPoolSortResult;
- for (ui32 i = 0; i < iterations; i++) {
- auto numbers = PrepareVectorToSort(vectorSize);
-
- TQuickSortTask::TThreadPoolParameters threadPoolParams(threads, 1, threadPool);
- TQuickSortTask::TParameters params(numbers, 0, numbers.size() - 1, &threadPoolParams);
-
- BENCH_START(thread);
-
- Y_ABORT_UNLESS(threadPool.AddAndOwn(THolder(new TQuickSortTask(params, activeThreadRegistry))));
- UNIT_ASSERT_C(activeThreadRegistry.WaitForAllInactive(60s), "timeout");
-
- threaPoolSortDurationTotal += std::chrono::duration_cast<std::chrono::microseconds>(BENCH_END(thread));
-
- if (i + 1 == iterations) {
- threadPoolSortResult = numbers;
- }
- }
-
- threadPool.Stop();
-
- return {threaPoolSortDurationTotal / iterations, threadPoolSortResult};
- }
-
- Y_UNIT_TEST(QuickSortActor) {
- const std::vector<ui32> threadss{1, 4};
- const std::vector<ui32> vectorSizes{100, 1'000, 1'000'000};
- const ui32 iterations = 3;
-
- std::cout << "sep=," << std::endl;
- std::cout << "size,threads,actor_time(us),thread_pool_time(us)" << std::endl;
-
- for (auto vectorSize : vectorSizes) {
- for (auto threads : threadss) {
- std::cerr << "vector size: " << vectorSize << ", threads: " << threads << std::endl;
-
- auto [actorSortDuration, actorSortResult] = BenchmarkQuickSortActor(threads, iterations, vectorSize);
- std::cerr << "actor sort duration: " << actorSortDuration.count() << "us" << std::endl;
-
- auto [threadPoolSortDuration, threadPoolSortResult] = BenchmarkQuickSortThreadPool(threads, iterations, vectorSize);
- std::cerr << "thread pool sort duration: " << threadPoolSortDuration.count() << "us" << std::endl;
-
- auto referenceVector = PrepareVectorToSort(vectorSize);
- std::sort(referenceVector.begin(), referenceVector.end());
-
- UNIT_ASSERT_EQUAL_C(actorSortResult, referenceVector,
- "vector size: " << vectorSize << "; threads: " << threads);
- UNIT_ASSERT_EQUAL_C(threadPoolSortResult, referenceVector,
- "vector size: " << vectorSize << "; threads: " << threads);
-
- std::cout << vectorSize << ","
- << threads << ","
- << actorSortDuration.count() << ","
- << threadPoolSortDuration.count() << std::endl;
- }
-
- std::cerr << "-----" << std::endl << std::endl;
- }
- }
-
- // KV-storage benchmark
-
- using TKvKey = std::string;
- using TKvValue = i32;
- using TDict = std::unordered_map<TKvKey, TKvValue>;
-
- struct TSearchStat {
- ui32 Found = 0;
- ui32 NotFound = 0;
-
- bool operator==(const TSearchStat& other) {
- return Found == other.Found && NotFound == other.NotFound;
- }
- };
-
- class TKvSearchTask : public IObjectInQueue {
- private:
- TKvKey Key_;
- const TDict& Dict_;
- TSearchStat SearchStat_ = {};
-
- public:
- TKvSearchTask() = delete;
- TKvSearchTask(TKvKey key, const TDict& dict)
- : Key_(key)
- , Dict_(dict)
- {}
-
- void Process(void*) override {
- if (Dict_.contains(Key_)) {
- SearchStat_.Found++;
- } else {
- SearchStat_.NotFound++;
- }
- }
- };
-
- class TEvKvSearch : public TEventLocal<TEvKvSearch, EvKvSearch> {
- public:
- TKvKey Key;
-
- public:
- TEvKvSearch() = delete;
- TEvKvSearch(TKvKey key)
- : Key(std::move(key))
- {}
- };
-
- class TEvKvSendRequests : public TEventLocal<TEvKvSendRequests, EvKvSendRequests> {
- public:
- const std::vector<std::string>& KeysToSearch;
- const std::vector<TActorId> SearchActorIds;
-
- public:
- TEvKvSendRequests() = delete;
- TEvKvSendRequests(const std::vector<std::string>& keysToSearch, std::vector<TActorId>&& searchActorIds)
- : KeysToSearch(keysToSearch)
- , SearchActorIds(std::move(searchActorIds))
- {}
- };
-
- class TKvSendRequestActor : public TActorBootstrapped<TKvSendRequestActor> {
- public:
- STFUNC(StateInit) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvKvSendRequests, Handle);
- default:
- Y_ABORT_UNLESS(false);
- }
- }
-
- void Bootstrap() {
- Become(&TThis::StateInit);
- }
-
- private:
- void Handle(TEvKvSendRequests::TPtr& ev) {
- auto evPtr = ev->Get();
- ui32 actorIdx = 0;
- for (auto& key : evPtr->KeysToSearch) {
- auto actorId = evPtr->SearchActorIds[actorIdx];
- actorIdx = (actorIdx + 1) % evPtr->SearchActorIds.size();
-
- Send(actorId, new TEvKvSearch(key));
- }
- }
- };
-
- class TKvSearchActor : public TActorBootstrapped<TKvSearchActor> {
- private:
- const TDict& Dict_;
- TSearchStat SearchStat_ = {};
- std::atomic<ui32> CompletedEvents_ = 0;
-
- public:
- TKvSearchActor() = delete;
- TKvSearchActor(const TDict& dict)
- : TActorBootstrapped<TKvSearchActor>()
- , Dict_(dict)
- {}
-
- STFUNC(StateInit) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvKvSearch, Handle);
- default:
- Y_ABORT_UNLESS(false);
- }
- }
-
- void Bootstrap() {
- Become(&TThis::StateInit);
- }
-
- const TSearchStat& SearchStat() {
- return SearchStat_;
- }
-
- ui32 CompletedEvents() {
- return CompletedEvents_;
- }
- private:
- void Handle(TEvKvSearch::TPtr& ev) {
- auto evPtr = ev->Get();
-
- if (Dict_.contains(evPtr->Key)) {
- SearchStat_.Found++;
- } else {
- SearchStat_.NotFound++;
- }
- CompletedEvents_++;
- }
- };
-
- TDict prepareKvSearchDict(const i32 dictSize) {
- std::string permutableString = "abcdefghijklm";
- TDict dict;
- for (i32 i = 0; i < dictSize; i++) {
- dict.emplace(permutableString, i);
- std::next_permutation(permutableString.begin(), permutableString.end());
- }
-
- return dict;
- }
-
- std::vector<std::string> prepareKeysToSearch(const TDict &dict, ui32 requestsNumber) {
- std::vector<std::string> keys;
- auto keyAppearances = requestsNumber / dict.size() + 1;
- keys.reserve(keyAppearances * dict.size());
-
- for (auto& [key, _] : dict) {
- for (ui32 i = 0; i < keyAppearances; i++) {
- keys.push_back(key);
-
- // keep the original key value to search
- if (i % 4 == 0) {
- continue;
- }
-
- // make non-exising key
- keys.back() += "nonexistingkey";
- }
- }
-
- Y_ABORT_UNLESS(keys.size() >= requestsNumber);
-
- std::random_shuffle(keys.begin(), keys.end());
- keys.resize(requestsNumber);
-
- return keys;
- }
-
- std::pair<std::vector<TKvSearchActor*>, std::vector<TActorId>> prepareKvSearchActors(
- TActorSystem* actorSystem, ui32 searchActorsNum, const std::vector<TDict>& dicts
- ) {
- std::vector<TKvSearchActor*> searchActors;
- std::vector<TActorId> searchActorIds;
- searchActors.reserve(searchActorsNum);
- searchActorIds.reserve(searchActorsNum);
- for (ui32 i = 0, dictIdx = 0; i < searchActorsNum; i++) {
- const auto& dict = dicts[dictIdx];
- dictIdx = (dictIdx + 1) % dicts.size();
-
- auto kvSearchActor = new TKvSearchActor(dict);
- auto kvSearchActorId = actorSystem->Register(kvSearchActor);
- searchActors.push_back(kvSearchActor);
- searchActorIds.push_back(kvSearchActorId);
- }
-
- return {searchActors, searchActorIds};
- }
-
- ui32 CalculateCompletedEvents(const std::vector<TKvSearchActor*>& actors) {
- ui32 completedEvents = 0;
- for (auto actor : actors) {
- completedEvents += actor->CompletedEvents();
- }
- return completedEvents;
- }
-
- TSearchStat CollectKvSearchActorStat(const std::vector<TKvSearchActor*>& actors) {
- TSearchStat stat;
- for (auto actor : actors) {
- stat.Found += actor->SearchStat().Found;
- stat.NotFound += actor->SearchStat().NotFound;
- }
- return stat;
- }
-
- std::pair<std::chrono::microseconds, TSearchStat> BenchmarkKvActor(
- ui32 threads, ui32 actors, ui32 iterations, const std::vector<TDict>& dicts, const std::vector<std::string>& keysToSearch
- ) {
- TSearchStat stat = {};
- auto kvSearchActorDuration = 0us;
-
- for (ui32 i = 0; i < iterations; i++) {
- auto actorSystem = PrepareActorSystem(threads);
- actorSystem->Start();
-
- auto [kvSearchActors, kvSearchActorIds] = prepareKvSearchActors(actorSystem.get(), actors, dicts);
-
- auto kvSendRequestActorId = actorSystem->Register(new TKvSendRequestActor());
-
- BENCH_START(kvSearch);
- actorSystem->Send(kvSendRequestActorId, new TEvKvSendRequests(keysToSearch, std::move(kvSearchActorIds)));
-
- // CondVar logic gives too much of overhead (2-10 times more than just sleep_for)
- while (CalculateCompletedEvents(kvSearchActors) < keysToSearch.size()) {
- std::this_thread::sleep_for(1us);
- }
-
- kvSearchActorDuration += std::chrono::duration_cast<std::chrono::microseconds>(BENCH_END(kvSearch));
-
- if (i + 1 == iterations) {
- stat = CollectKvSearchActorStat(kvSearchActors);
- }
- }
-
- return {kvSearchActorDuration / iterations, stat};
- }
-
- std::pair<std::chrono::microseconds, TSearchStat> BenchmarkKvActorExternalSender(
- ui32 threads, ui32 actors, ui32 iterations, const std::vector<TDict>& dicts, const std::vector<std::string>& keysToSearch
- ) {
- TSearchStat stat = {};
- auto kvSearchActorDuration = 0us;
- for (ui32 i = 0; i < iterations; i++) {
- auto actorSystem = PrepareActorSystem(threads);
- actorSystem->Start();
-
- auto [kvSearchActors, kvSearchActorIds] = prepareKvSearchActors(actorSystem.get(), actors, dicts);
-
- BENCH_START(kvSearch);
- ui32 actorIdToUseIndex = 0;
- for (auto& key : keysToSearch) {
- actorSystem->Send(kvSearchActorIds[actorIdToUseIndex], new TEvKvSearch(key));
- actorIdToUseIndex = (actorIdToUseIndex + 1) % kvSearchActorIds.size();
- }
-
- // CondVar logic gives too much of overhead (2-10 times more than just sleep_for)
- while (CalculateCompletedEvents(kvSearchActors) < keysToSearch.size()) {
- std::this_thread::sleep_for(1us);
- }
-
- kvSearchActorDuration += std::chrono::duration_cast<std::chrono::microseconds>(BENCH_END(kvSearch));
-
- if (i + 1 == iterations) {
- stat = CollectKvSearchActorStat(kvSearchActors);
- }
- }
-
- return {kvSearchActorDuration / iterations, stat};
- }
-
- std::chrono::microseconds BenchmarkKvThreadPool(
- ui32 threads, ui32 iterations, const TDict& dict, const std::vector<std::string>& keysToSearch
- ) {
- TThreadPool threadPool;
-
- auto kvSearchActorDuration = 0us;
- for (ui32 i = 0; i < iterations; i++) {
- threadPool.Start(threads);
-
- BENCH_START(kvSearch);
-
- for (auto& key : keysToSearch) {
- Y_ABORT_UNLESS(threadPool.AddAndOwn(THolder(new TKvSearchTask(key, dict))));
- }
-
- // CondVar logic gives too much of overhead (2-10 times more than just sleep_for)
- while (threadPool.Size() > 0) {
- std::this_thread::sleep_for(1us);
- }
- threadPool.Stop();
-
- kvSearchActorDuration += std::chrono::duration_cast<std::chrono::microseconds>(BENCH_END(kvSearch));
- }
-
- return {kvSearchActorDuration / iterations};
- }
-
- std::pair<std::chrono::microseconds, TSearchStat> BenchmarkKvSingleThread(
- ui32 iterations, const TDict& dict, const std::vector<std::string>& keysToSearch
- ) {
- TSearchStat stat = {};
- auto kvSearchDuration = 0us;
- for (ui32 i = 0; i < iterations; i++) {
- TSearchStat iterationStat = {};
- BENCH_START(kvSearch);
- for (auto& key : keysToSearch) {
- if (dict.contains(key)) {
- iterationStat.Found++;
- } else {
- iterationStat.NotFound++;
- }
- }
- kvSearchDuration += std::chrono::duration_cast<std::chrono::microseconds>(BENCH_END(kvSearch));
-
- if (i + 1 == iterations) {
- stat = iterationStat;
- }
- }
-
- return {kvSearchDuration / iterations, stat};
- }
-
- Y_UNIT_TEST(KvActor) {
- const bool forCI = true;
-
- using TNumbers = std::vector<ui32>;
- const TNumbers threadNumbers = forCI ? TNumbers{1} : TNumbers{1, 4, 8};
- const TNumbers actorNumbers = forCI ? TNumbers{1, 8} : TNumbers{1, 4, 8, 16, 32, 64};
- const TNumbers dictSizes = forCI ? TNumbers{1'000} : TNumbers{1'000, 1'000'000};
- const TNumbers dictsNumbers = forCI ? TNumbers{1} : TNumbers{1, 8};
- const ui32 iterations = 5;
-
- std::cout << "sep=," << std::endl;
- std::cout << "requests_number,dicts_number,dict_size,threads,actors,actor_time(us),actor_ext_time(us),thread_pool_time(us),single_thread_time(us)" << std::endl;
-
- for (auto dictsNumber : dictsNumbers) {
- for (auto dictSize : dictSizes) {
- const auto dict = prepareKvSearchDict(dictSize);
- const ui32 requestsNumber = forCI ? 10'000 : 1'000'000;
- const auto keysToSearch = prepareKeysToSearch(dict, requestsNumber);
-
- for (auto threads : threadNumbers) {
- std::cerr << "requestsNumber: " << requestsNumber
- << ", dictSize: " << dictSize
- << ", threads: " << threads << std::endl;
-
- auto tpKvDuration = BenchmarkKvThreadPool(threads, iterations, dict, keysToSearch);
- std::cerr << "kv search threadpool duration: " << tpKvDuration.count() << "us" << std::endl;
-
- auto [singleThreadKvDuration, singleThreadKvStat] = BenchmarkKvSingleThread(iterations, dict, keysToSearch);
- std::cerr << "kv search single thread duration: " << singleThreadKvDuration.count() << "us" << std::endl;
-
- std::vector<TDict> dicts(dictsNumber, dict);
-
- for (auto actors : actorNumbers) {
- std::cerr << "----" << std::endl
- << "requestsNumber: " << requestsNumber
- << ", dictsNumber: " << dictsNumber
- << ", dictSize: " << dictSize
- << ", threads: " << threads
- << ", actors: " << actors << std::endl;
-
- auto [actorKvDuration, actorKvStat] = BenchmarkKvActor(threads, actors, iterations, dicts, keysToSearch);
- std::cerr << "kv search actor duration: " << actorKvDuration.count() << "us" << std::endl;
-
- auto [actorKvExtDuration, actorKvExtStat] =
- BenchmarkKvActorExternalSender(threads, actors, iterations, dicts, keysToSearch);
- std::cerr << "kv search actor with external message sender duration: "
- << actorKvExtDuration.count() << "us" << std::endl;
- Y_UNUSED(actorKvExtStat);
-
-
- UNIT_ASSERT_EQUAL_C(actorKvStat, singleThreadKvStat,
- "single thread found/not found: " << singleThreadKvStat.Found << "/" << singleThreadKvStat.NotFound << "; "
- "actor stat found/not found: " << actorKvStat.Found << "/" << actorKvStat.NotFound);
-
- std::cout << requestsNumber << ","
- << dictsNumber << ","
- << dictSize << ","
- << threads << ","
- << actors << ","
- << actorKvDuration.count() << ","
- << actorKvExtDuration.count() << ","
- << tpKvDuration.count() << ","
- << singleThreadKvDuration.count() << std::endl;
- }
- std::cerr << "----" << std::endl;
- }
- }
- }
- }
-
- // vector sum benchmark
-
- i64 CalculateOddSum(const TContainer& numbers) {
- i64 result = 0;
- for (auto x : numbers) {
- if (x % 2 == 1) {
- result += x;
- }
- }
-
- return result;
- }
-
- TContainer prepareVectorToSum(const ui32 vectorSize) {
- TContainer numbers;
- numbers.reserve(vectorSize);
- for (ui32 i = 0; i < vectorSize; i++) {
- numbers.push_back(i + 1);
- }
-
- return numbers;
- }
-
- class TEvSumVector : public TEventLocal<TEvSumVector, EvSumVector> {
- public:
- const TContainer Numbers;
-
- public:
- TEvSumVector() = delete;
-
- TEvSumVector(TContainer&& numbers)
- : Numbers(std::move(numbers))
- {}
- };
-
- class TEvSumVectorResult : public TEventLocal<TEvSumVectorResult, EvSumVectorResult> {
- public:
- const i64 Sum = 0;
-
- public:
- TEvSumVectorResult(i64 sum)
- : Sum(sum)
- {}
- };
-
- class TEvSumSendRequests : public TEventLocal<TEvSumSendRequests, EvSumSendRequests> {
- public:
- const ui32 VectorSize;
- const ui32 RequestsNumber;
- const TActorIds ActorIds;
-
- public:
- TEvSumSendRequests() = delete;
- TEvSumSendRequests(ui32 vectorSize, ui32 requestsNumber, TActorIds actorIds)
- : VectorSize(vectorSize)
- , RequestsNumber(requestsNumber)
- , ActorIds(actorIds)
- {}
- };
-
- class TSumProxyActor : public TActorBootstrapped<TSumProxyActor> {
- private:
- i64 LastSum_ = 0;
- ui32 NumberOfResults_ = 0;
- ui32 ExpectedResults_ = 0;
- ui32 VectorSize_ = 0;
- TActorIds SumVectorActorIds_ = {};
- ui32 LastUsedActor_ = 0;
-
- std::mutex NumberOfResultsMutex_;
- std::condition_variable NumberOfResultsCv_;
-
- public:
- STFUNC(StateInit) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvSumSendRequests, HandleRequest);
- hFunc(TEvSumVectorResult, HandleResult);
- default:
- Y_ABORT_UNLESS(false);
- }
- }
-
- void Bootstrap() {
- Become(&TThis::StateInit);
- }
-
- i64 LastSum() {
- return LastSum_;
- }
-
- bool WaitForResults(std::chrono::microseconds timeout = 1ms, bool nonZero = true) {
- std::unique_lock lock(NumberOfResultsMutex_);
- NumberOfResultsCv_.wait_for(lock, timeout, [this, nonZero] {
- return ((nonZero && NumberOfResults_ != 0) || !nonZero)
- && NumberOfResults_ == ExpectedResults_;
- });
- return NumberOfResults_ == ExpectedResults_;
- }
-
- void ShiftLastUsedActor(ui32 shift) {
- LastUsedActor_ += shift;
- }
-
- private:
- TActorId NextActorId() {
- auto actorId = SumVectorActorIds_[LastUsedActor_ % SumVectorActorIds_.size()];
- LastUsedActor_ = (LastUsedActor_ + 1) % SumVectorActorIds_.size();
-
- return actorId;
- }
-
- bool SendVectorIfNeeded() {
- if (NumberOfResults_ < ExpectedResults_) {
- Send(NextActorId(), new TEvSumVector(prepareVectorToSum(VectorSize_)));
- return true;
- }
- return false;
- }
-
- void HandleRequest(TEvSumSendRequests::TPtr& ev) {
- auto evPtr = ev->Get();
- ExpectedResults_ = evPtr->RequestsNumber;
- VectorSize_ = evPtr->VectorSize;
- SumVectorActorIds_ = evPtr->ActorIds;
-
- {
- std::unique_lock lock(NumberOfResultsMutex_);
- NumberOfResults_ = 0;
-
- SendVectorIfNeeded();
- }
- }
-
- void HandleResult(TEvSumVectorResult::TPtr& ev) {
- LastSum_ = ev->Get()->Sum;
- {
- std::unique_lock lock(NumberOfResultsMutex_);
- NumberOfResults_++;
-
- if (!SendVectorIfNeeded()) {
- NumberOfResultsCv_.notify_all();
- }
- }
- }
- };
-
- class TSumVectorActor : public TActorBootstrapped<TSumVectorActor> {
- private:
- TActorId ResultActorId_;
-
- public:
- STFUNC(StateInit) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvSumVector, Handle);
- default:
- Y_ABORT_UNLESS(false);
- }
- }
-
- void Bootstrap() {
- Become(&TThis::StateInit);
- }
-
- private:
- void Handle(TEvSumVector::TPtr& ev) {
- auto evPtr = ev->Get();
- auto oddSum = CalculateOddSum(evPtr->Numbers);
-
- Send(ev->Sender, new TEvSumVectorResult(oddSum));
- }
- };
-
- std::vector<TActorId> prepareSumActors(TActorSystem* actorSystem, ui32 actorsNumber) {
- std::vector<TActorId> actorIds;
- actorIds.reserve(actorsNumber);
- for (ui32 i = 0; i < actorsNumber; i++) {
- actorIds.push_back(actorSystem->Register(new TSumVectorActor()));
- }
- return actorIds;
- }
-
- std::pair<std::vector<TSumProxyActor*>, std::vector<TActorId>> prepareProxyActors(
- TActorSystem* actorSystem, ui32 actorsNumber
- ) {
- std::pair<std::vector<TSumProxyActor*>, std::vector<TActorId>> result;
- auto& [actors, actorIds] = result;
- actors.reserve(actorsNumber);
- actorIds.reserve(actorsNumber);
- for (ui32 i = 0; i < actorsNumber; i++) {
- actors.push_back(new TSumProxyActor());
- actorIds.push_back(actorSystem->Register(actors.back()));
- actors.back()->ShiftLastUsedActor(i);
- }
-
- return result;
- }
-
- std::chrono::microseconds calcTimeoutForSumVector(
- ui32 vectorSize, ui32 iterations, ui32 proxyActorsNum, ui32 sumActorsNum, ui32 threadsNum
- ) {
- auto expectedMaxTimePerMillion = 100000us;
- auto vectorSizeRatio = vectorSize / 1000000 + 1;
-
- return expectedMaxTimePerMillion * vectorSizeRatio * iterations * proxyActorsNum / std::min(threadsNum, sumActorsNum);
- }
-
- bool WaitForSumActorResult(const std::vector<TSumProxyActor*>& actors, std::chrono::microseconds timeout = 1ms) {
- for (auto& actor : actors) {
- if (!actor->WaitForResults(timeout)) {
- return false;
- }
- }
- return true;
- }
-
- std::pair<std::chrono::microseconds, i64> BenchmarkSumVectorActor(
- ui32 threads,
- ui32 proxyActorsNumber,
- ui32 sumActorsNumber,
- ui32 iterations,
- ui32 vectorSize
- ) {
- auto actorSystem = PrepareActorSystem(threads);
- actorSystem->Start();
-
- auto sumActorIds = prepareSumActors(actorSystem.get(), sumActorsNumber);
- auto [proxyActors, proxyActorIds] = prepareProxyActors(actorSystem.get(), proxyActorsNumber);
-
- auto timeout = calcTimeoutForSumVector(vectorSize, iterations, proxyActorsNumber, sumActorsNumber, threads);
-
- BENCH_START(sumVectorActor);
-
- for (auto proxyActorId : proxyActorIds) {
- actorSystem->Send(proxyActorId, new TEvSumSendRequests(vectorSize, iterations, sumActorIds));
- }
-
- UNIT_ASSERT_C(WaitForSumActorResult(proxyActors, timeout), "timeout");
-
- auto totalDuration = std::chrono::duration_cast<std::chrono::microseconds>(BENCH_END(sumVectorActor));
- auto checkSum = proxyActors.back()->LastSum();
-
- return {totalDuration / iterations, checkSum};
- }
-
- Y_UNIT_TEST(SumVector) {
- using TVui64 = std::vector<ui64>;
- const bool forCI = true;
- const TVui64 vectorSizes = forCI ?
- TVui64{1'000, 1'000'000} : TVui64{1'000, 1'000'000, 10'000'000, 100'000'000};
- const TVui64 threadsNumbers = forCI ? TVui64{1} : TVui64{1, 4};
- const TVui64 proxyActorsNumbers = forCI ? TVui64{1} : TVui64{1, 4};
- const TVui64 sumActorsNumbers = forCI ? TVui64{1} : TVui64{1, 8, 32};
- const ui32 iterations = 30;
-
- std::cout << "sep=," << std::endl;
- std::cout << "size,threads,proxy_actors,sum_actors,duration(us)" << std::endl;
-
- for (auto vectorSize : vectorSizes) {
- for (auto threads : threadsNumbers) {
- for (auto proxyActors : proxyActorsNumbers) {
- for (auto sumActors : sumActorsNumbers) {
- std::cerr << "vector size: " << vectorSize
- << ", threads: " << threads
- << ", proxy actors: " << proxyActors
- << ", sum actors: " << sumActors << std::endl;
-
- auto [duration, resultSum] = BenchmarkSumVectorActor(
- threads, proxyActors, sumActors, iterations, vectorSize);
- std::cerr << "duration: " << duration.count() << "us" << std::endl;
-
- const i64 referenceSum = vectorSize * vectorSize / 4;
- UNIT_ASSERT_EQUAL_C(
- resultSum, referenceSum,
- resultSum << "!=" << referenceSum << "; failed on vectorSize=" << vectorSize
- << ", threads=" << threads
- << ", proxyActors=" << proxyActors
- << ", sumActors=" << sumActors);
-
- std::cout << vectorSize << ","
- << threads << ","
- << proxyActors << ","
- << sumActors << ","
- << duration.count()
- << std::endl;
- }
- }
- }
- }
- }
-}
diff --git a/library/cpp/actors/core/buffer.cpp b/library/cpp/actors/core/buffer.cpp
deleted file mode 100644
index 91ff4dde68..0000000000
--- a/library/cpp/actors/core/buffer.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "buffer.h"
-
-#include <util/system/yassert.h>
-
-#include <algorithm>
-
-TBufferBase::TBufferBase(size_t size) noexcept
- : Size(size)
-{
-}
-
-size_t
-TBufferBase::GetSize() const noexcept {
- return Size;
-}
-
-void TBufferBase::SetSize(size_t size) noexcept {
- Size = size;
-}
-
-/////////////////////////////////////////////////////////////////////
-
-template <typename PointerType>
-TBufferBaseT<PointerType>::TBufferBaseT(PointerType data, size_t size) noexcept
- : TBufferBase(size)
- , Data(data)
-{
-}
-
-template <typename PointerType>
-PointerType
-TBufferBaseT<PointerType>::GetPointer() const noexcept {
- return Data;
-}
-
-template <typename PointerType>
-void TBufferBaseT<PointerType>::Assign(PointerType data, size_t size) noexcept {
- Data = data;
- Size = size;
-}
-
-template <>
-void TBufferBaseT<void*>::Cut(size_t offset) noexcept {
- Y_DEBUG_ABORT_UNLESS(offset <= Size);
- Data = static_cast<char*>(Data) + offset;
- TBufferBase::Size -= offset;
-}
-
-template <>
-void TBufferBaseT<const void*>::Cut(size_t offset) noexcept {
- Y_DEBUG_ABORT_UNLESS(offset <= Size);
- Data = static_cast<const char*>(Data) + offset;
- TBufferBase::Size -= offset;
-}
-
-template class TBufferBaseT<void*>;
-template class TBufferBaseT<const void*>;
-
-/////////////////////////////////////////////////////////////////////
-
-TConstBuffer::TConstBuffer(const void* data, size_t size) noexcept
- : TBufferBaseT<const void*>(data, size)
-{
-}
-
-TConstBuffer::TConstBuffer(const TMutableBuffer& buffer) noexcept
- : TBufferBaseT<const void*>(buffer.GetPointer(), buffer.GetSize())
-{
-}
-
-TConstBuffer
-TConstBuffer::Offset(ptrdiff_t offset, size_t size) const noexcept {
- return TConstBuffer(static_cast<const char*>(Data) + offset, std::min(Size - offset, size));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TMutableBuffer::TMutableBuffer(void* data, size_t size) noexcept
- : TBufferBaseT<void*>(data, size)
-{
-}
-
-TMutableBuffer
-TMutableBuffer::Offset(ptrdiff_t offset, size_t size) const noexcept {
- return TMutableBuffer(static_cast<char*>(Data) + offset, std::min(Size - offset, size));
-}
-
-size_t
-TMutableBuffer::CopyFrom(const TConstBuffer& buffer) const noexcept {
- const auto size = std::min(Size, buffer.Size);
- std::memcpy(Data, buffer.Data, size);
- return size;
-}
diff --git a/library/cpp/actors/core/buffer.h b/library/cpp/actors/core/buffer.h
deleted file mode 100644
index 95425046d6..0000000000
--- a/library/cpp/actors/core/buffer.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#pragma once
-
-#include <limits>
-
-class TConstBuffer;
-class TMutableBuffer;
-
-class TBufferBase {
-public:
- size_t GetSize() const noexcept;
-
- void SetSize(size_t newSize) noexcept;
-
-protected:
- TBufferBase(size_t size = 0) noexcept;
-
- size_t Size;
-};
-
-template <typename PointerType>
-class TBufferBaseT: public TBufferBase {
-public:
- PointerType GetPointer() const noexcept;
-
- void Cut(size_t offset) noexcept;
-
- void Assign(PointerType data = nullptr, size_t size = 0U) noexcept;
-
-protected:
- TBufferBaseT(PointerType data, size_t size) noexcept;
-
- PointerType Data;
-};
-
-/// Represents constant memory buffer, but do not owns it.
-class TConstBuffer: public TBufferBaseT<const void*> {
- friend class TMutableBuffer;
-
-public:
- TConstBuffer(const TMutableBuffer& buffer) noexcept;
-
- TConstBuffer(const void* data = nullptr, size_t size = 0U) noexcept;
-
- TConstBuffer Offset(ptrdiff_t offset, size_t size = std::numeric_limits<size_t>::max()) const noexcept;
-};
-
-/// Represents mutable memory buffer, but do not owns it.
-class TMutableBuffer: public TBufferBaseT<void*> {
- friend class TConstBuffer;
-
-public:
- TMutableBuffer(void* data = nullptr, size_t size = 0U) noexcept;
-
- TMutableBuffer(const TMutableBuffer& value) noexcept
- : TBufferBaseT<void*>(value)
- {
- }
-
- TMutableBuffer Offset(ptrdiff_t offset, size_t size = std::numeric_limits<size_t>::max()) const noexcept;
-
- size_t CopyFrom(const TConstBuffer& buffer) const noexcept;
-};
diff --git a/library/cpp/actors/core/callstack.cpp b/library/cpp/actors/core/callstack.cpp
deleted file mode 100644
index 559cc73550..0000000000
--- a/library/cpp/actors/core/callstack.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "callstack.h"
-#include <util/thread/singleton.h>
-
-#ifdef USE_ACTOR_CALLSTACK
-
-namespace NActors {
- namespace {
- void (*PreviousFormatBackTrace)(IOutputStream*) = 0;
- ui32 ActorBackTraceEnableCounter = 0;
- }
-
- void ActorFormatBackTrace(IOutputStream* out) {
- TStringStream str;
- PreviousFormatBackTrace(&str);
- str << Endl;
- TCallstack::DumpCallstack(str);
- *out << str.Str();
- }
-
- void EnableActorCallstack() {
- if (ActorBackTraceEnableCounter == 0) {
- Y_ABORT_UNLESS(PreviousFormatBackTrace == 0);
- PreviousFormatBackTrace = SetFormatBackTraceFn(ActorFormatBackTrace);
- }
-
- ++ActorBackTraceEnableCounter;
- }
-
- void DisableActorCallstack() {
- --ActorBackTraceEnableCounter;
-
- if (ActorBackTraceEnableCounter == 0) {
- Y_ABORT_UNLESS(PreviousFormatBackTrace);
- SetFormatBackTraceFn(PreviousFormatBackTrace);
- PreviousFormatBackTrace = 0;
- }
- }
-
- TCallstack::TCallstack()
- : BeginIdx(0)
- , Size(0)
- , LinesToSkip(0)
- {
- }
-
- void TCallstack::SetLinesToSkip() {
- TTrace record;
- LinesToSkip = BackTrace(record.Data, TTrace::CAPACITY);
- }
-
- void TCallstack::Trace() {
- size_t currentIdx = (BeginIdx + Size) % RECORDS;
- if (Size == RECORDS) {
- ++BeginIdx;
- } else {
- ++Size;
- }
- TTrace& record = Record[currentIdx];
- record.Size = BackTrace(record.Data, TTrace::CAPACITY);
- record.LinesToSkip = LinesToSkip;
- }
-
- void TCallstack::TraceIfEmpty() {
- if (Size == 0) {
- LinesToSkip = 0;
- Trace();
- }
- }
-
- TCallstack& TCallstack::GetTlsCallstack() {
- return *FastTlsSingleton<TCallstack>();
- }
-
- void TCallstack::DumpCallstack(TStringStream& str) {
- TCallstack& callstack = GetTlsCallstack();
- for (int i = callstack.Size - 1; i >= 0; --i) {
- TTrace& record = callstack.Record[(callstack.BeginIdx + i) % RECORDS];
- str << Endl << "Trace entry " << i << Endl << Endl;
- size_t size = record.Size;
- if (size > record.LinesToSkip && size < TTrace::CAPACITY) {
- size -= record.LinesToSkip;
- }
- if (size > RECORDS_TO_SKIP) {
- FormatBackTrace(&str, &record.Data[RECORDS_TO_SKIP], size - RECORDS_TO_SKIP);
- } else {
- FormatBackTrace(&str, record.Data, size);
- }
- str << Endl;
- }
- }
-}
-
-#endif
diff --git a/library/cpp/actors/core/callstack.h b/library/cpp/actors/core/callstack.h
deleted file mode 100644
index 034d0becf1..0000000000
--- a/library/cpp/actors/core/callstack.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#pragma once
-
-#ifndef NDEBUG
-//#define ENABLE_ACTOR_CALLSTACK
-#endif
-
-#ifdef ENABLE_ACTOR_CALLSTACK
-#include "defs.h"
-#include <util/system/backtrace.h>
-#include <util/stream/str.h>
-#include <util/generic/deque.h>
-#define USE_ACTOR_CALLSTACK
-
-namespace NActors {
- struct TCallstack {
- struct TTrace {
- static const size_t CAPACITY = 50;
- void* Data[CAPACITY];
- size_t Size;
- size_t LinesToSkip;
-
- TTrace()
- : Size(0)
- , LinesToSkip(0)
- {
- }
- };
-
- static const size_t RECORDS = 8;
- static const size_t RECORDS_TO_SKIP = 2;
- TTrace Record[RECORDS];
- size_t BeginIdx;
- size_t Size;
- size_t LinesToSkip;
-
- TCallstack();
- void SetLinesToSkip();
- void Trace();
- void TraceIfEmpty();
- static TCallstack& GetTlsCallstack();
- static void DumpCallstack(TStringStream& str);
- };
-
- void EnableActorCallstack();
- void DisableActorCallstack();
-
-}
-
-#else
-
-namespace NActors {
- inline void EnableActorCallstack(){}
-
- inline void DisableActorCallstack(){}
-
-}
-
-#endif
diff --git a/library/cpp/actors/core/config.h b/library/cpp/actors/core/config.h
deleted file mode 100644
index 04bdd6aebe..0000000000
--- a/library/cpp/actors/core/config.h
+++ /dev/null
@@ -1,260 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include <library/cpp/actors/util/cpumask.h>
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-#include <util/datetime/base.h>
-#include <util/generic/ptr.h>
-#include <util/generic/string.h>
-#include <util/generic/vector.h>
-
-namespace NActors {
-
- struct TBalancingConfig {
- // Default cpu count (used during overload). Zero value disables this pool balancing
- // 1) Sum of `Cpus` on all pools cannot be changed without restart
- // (changing cpu mode between Shared and Assigned is not implemented yet)
- // 2) This sum must be equal to TUnitedWorkersConfig::CpuCount,
- // otherwise `CpuCount - SUM(Cpus)` cpus will be in Shared mode (i.e. actorsystem 2.0)
- ui32 Cpus = 0;
-
- ui32 MinCpus = 0; // Lower balancing bound, should be at least 1, and not greater than `Cpus`
- ui32 MaxCpus = 0; // Higher balancing bound, should be not lower than `Cpus`
- ui8 Priority = 0; // Priority of pool to obtain cpu due to balancing (higher is better)
- ui64 ToleratedLatencyUs = 0; // p100-latency threshold indicating that more cpus are required by pool
- };
-
- struct TBalancerConfig {
- ui64 PeriodUs = 15000000; // Time between balancer steps
- };
-
- enum class EASProfile {
- Default,
- LowCpuConsumption,
- LowLatency,
- };
-
- struct TBasicExecutorPoolConfig {
- static constexpr TDuration DEFAULT_TIME_PER_MAILBOX = TDuration::MilliSeconds(10);
- static constexpr ui32 DEFAULT_EVENTS_PER_MAILBOX = 100;
-
- ui32 PoolId = 0;
- TString PoolName;
- ui32 Threads = 1;
- ui64 SpinThreshold = 100;
- TCpuMask Affinity; // Executor thread affinity
- TDuration TimePerMailbox = DEFAULT_TIME_PER_MAILBOX;
- ui32 EventsPerMailbox = DEFAULT_EVENTS_PER_MAILBOX;
- int RealtimePriority = 0;
- i16 MinThreadCount = 0;
- i16 MaxThreadCount = 0;
- i16 DefaultThreadCount = 0;
- i16 Priority = 0;
- i16 SharedExecutorsCount = 0;
- i16 SoftProcessingDurationTs = 0;
- EASProfile ActorSystemProfile = EASProfile::Default;
- };
-
- struct TIOExecutorPoolConfig {
- ui32 PoolId = 0;
- TString PoolName;
- ui32 Threads = 1;
- TCpuMask Affinity; // Executor thread affinity
- };
-
- struct TUnitedExecutorPoolConfig {
- static constexpr TDuration DEFAULT_TIME_PER_MAILBOX = TDuration::MilliSeconds(10);
- static constexpr ui32 DEFAULT_EVENTS_PER_MAILBOX = 100;
-
- ui32 PoolId = 0;
- TString PoolName;
-
- // Resource sharing
- ui32 Concurrency = 0; // Limits simultaneously running mailboxes count if set to non-zero value (do not set if Balancing.Cpus != 0)
- TPoolWeight Weight = 0; // Weight in fair cpu-local pool scheduler
- TCpuMask Allowed; // Allowed CPUs for workers to run this pool on (ignored if balancer works, i.e. actorsystem 1.5)
-
- // Single mailbox execution limits
- TDuration TimePerMailbox = DEFAULT_TIME_PER_MAILBOX;
- ui32 EventsPerMailbox = DEFAULT_EVENTS_PER_MAILBOX;
-
- // Long-term balancing
- TBalancingConfig Balancing;
- };
-
- struct TUnitedWorkersConfig {
- ui32 CpuCount = 0; // Total CPUs running united workers (i.e. TBasicExecutorPoolConfig::Threads analog); set to zero to disable united workers
- ui64 SpinThresholdUs = 100; // Limit for active spinning in case all pools became idle
- ui64 PoolLimitUs = 500; // Soft limit on pool execution
- ui64 EventLimitUs = 100; // Hard limit on last event execution exceeding pool limit
- ui64 LimitPrecisionUs = 100; // Maximum delay of timer on limit excess (delay needed to avoid settimer syscall on every pool switch)
- ui64 FastWorkerPriority = 10; // Real-time priority of workers not exceeding hard limits
- ui64 IdleWorkerPriority = 20; // Real-time priority of standby workers waiting for hard preemption on timers (should be greater than FastWorkerPriority)
- TCpuMask Allowed; // Allowed CPUs for workers to run on (every worker has affinity for exactly one cpu)
- bool NoRealtime = false; // For environments w/o permissions for RT-threads
- bool NoAffinity = false; // For environments w/o permissions for cpu affinity
- TBalancerConfig Balancer;
- };
-
- struct TSelfPingInfo {
- NMonitoring::TDynamicCounters::TCounterPtr AvgPingCounter;
- NMonitoring::TDynamicCounters::TCounterPtr AvgPingCounterWithSmallWindow;
- ui32 MaxAvgPingUs;
- };
-
- struct TCpuManagerConfig {
- TUnitedWorkersConfig UnitedWorkers;
- TVector<TBasicExecutorPoolConfig> Basic;
- TVector<TIOExecutorPoolConfig> IO;
- TVector<TUnitedExecutorPoolConfig> United;
- TVector<TSelfPingInfo> PingInfoByPool;
-
- ui32 GetExecutorsCount() const {
- return Basic.size() + IO.size() + United.size();
- }
-
- TString GetPoolName(ui32 poolId) const {
- for (const auto& p : Basic) {
- if (p.PoolId == poolId) {
- return p.PoolName;
- }
- }
- for (const auto& p : IO) {
- if (p.PoolId == poolId) {
- return p.PoolName;
- }
- }
- for (const auto& p : United) {
- if (p.PoolId == poolId) {
- return p.PoolName;
- }
- }
- Y_ABORT("undefined pool id: %" PRIu32, (ui32)poolId);
- }
-
- std::optional<ui32> GetThreadsOptional(ui32 poolId) const {
- for (const auto& p : Basic) {
- if (p.PoolId == poolId) {
- return p.DefaultThreadCount;
- }
- }
- for (const auto& p : IO) {
- if (p.PoolId == poolId) {
- return p.Threads;
- }
- }
- for (const auto& p : United) {
- if (p.PoolId == poolId) {
- return p.Concurrency ? p.Concurrency : UnitedWorkers.CpuCount;
- }
- }
- return {};
- }
-
- ui32 GetThreads(ui32 poolId) const {
- auto result = GetThreadsOptional(poolId);
- Y_ABORT_UNLESS(result, "undefined pool id: %" PRIu32, (ui32)poolId);
- return *result;
- }
- };
-
- struct TSchedulerConfig {
- TSchedulerConfig(
- ui64 resolution = 1024,
- ui64 spinThreshold = 100,
- ui64 progress = 10000,
- bool useSchedulerActor = false)
- : ResolutionMicroseconds(resolution)
- , SpinThreshold(spinThreshold)
- , ProgressThreshold(progress)
- , UseSchedulerActor(useSchedulerActor)
- {}
-
- ui64 ResolutionMicroseconds = 1024;
- ui64 SpinThreshold = 100;
- ui64 ProgressThreshold = 10000;
- bool UseSchedulerActor = false; // False is default because tests use scheduler thread
- ui64 RelaxedSendPaceEventsPerSecond = 200000;
- ui64 RelaxedSendPaceEventsPerCycle = RelaxedSendPaceEventsPerSecond * ResolutionMicroseconds / 1000000;
- // For resolution >= 250000 microseconds threshold is SendPace
- // For resolution <= 250 microseconds threshold is 20 * SendPace
- ui64 RelaxedSendThresholdEventsPerSecond = RelaxedSendPaceEventsPerSecond *
- (20 - ((20 - 1) * ClampVal(ResolutionMicroseconds, ui64(250), ui64(250000)) - 250) / (250000 - 250));
- ui64 RelaxedSendThresholdEventsPerCycle = RelaxedSendThresholdEventsPerSecond * ResolutionMicroseconds / 1000000;
-
- // Optional subsection for scheduler counters (usually subsystem=utils)
- NMonitoring::TDynamicCounterPtr MonCounters = nullptr;
- };
-
- struct TCpuAllocation {
- struct TPoolAllocation {
- TPoolId PoolId;
- TPoolWeight Weight;
-
- TPoolAllocation(TPoolId poolId = 0, TPoolWeight weight = 0)
- : PoolId(poolId)
- , Weight(weight)
- {}
- };
-
- TCpuId CpuId;
- TVector<TPoolAllocation> AllowedPools;
-
- TPoolsMask GetPoolsMask() const {
- TPoolsMask mask = 0;
- for (const auto& pa : AllowedPools) {
- if (pa.PoolId < MaxPools) {
- mask &= (1ull << pa.PoolId);
- }
- }
- return mask;
- }
-
- bool HasPool(TPoolId pool) const {
- for (const auto& pa : AllowedPools) {
- if (pa.PoolId == pool) {
- return true;
- }
- }
- return false;
- }
- };
-
- struct TCpuAllocationConfig {
- TVector<TCpuAllocation> Items;
-
- TCpuAllocationConfig(const TCpuMask& available, const TCpuManagerConfig& cfg) {
- for (const TUnitedExecutorPoolConfig& pool : cfg.United) {
- Y_ABORT_UNLESS(pool.PoolId < MaxPools, "wrong PoolId of united executor pool: %s(%d)",
- pool.PoolName.c_str(), (pool.PoolId));
- }
- ui32 allocated[MaxPools] = {0};
- for (TCpuId cpu = 0; cpu < available.Size() && Items.size() < cfg.UnitedWorkers.CpuCount; cpu++) {
- if (available.IsSet(cpu)) {
- TCpuAllocation item;
- item.CpuId = cpu;
- for (const TUnitedExecutorPoolConfig& pool : cfg.United) {
- if (cfg.UnitedWorkers.Allowed.IsEmpty() || cfg.UnitedWorkers.Allowed.IsSet(cpu)) {
- if (pool.Allowed.IsEmpty() || pool.Allowed.IsSet(cpu)) {
- item.AllowedPools.emplace_back(pool.PoolId, pool.Weight);
- allocated[pool.PoolId]++;
- }
- }
- }
- if (!item.AllowedPools.empty()) {
- Items.push_back(item);
- }
- }
- }
- for (const TUnitedExecutorPoolConfig& pool : cfg.United) {
- Y_ABORT_UNLESS(allocated[pool.PoolId] > 0, "unable to allocate cpu for united executor pool: %s(%d)",
- pool.PoolName.c_str(), (pool.PoolId));
- }
- }
-
- operator bool() const {
- return !Items.empty();
- }
- };
-
-}
diff --git a/library/cpp/actors/core/cpu_manager.cpp b/library/cpp/actors/core/cpu_manager.cpp
deleted file mode 100644
index 24b3161e3c..0000000000
--- a/library/cpp/actors/core/cpu_manager.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "cpu_manager.h"
-#include "probes.h"
-
-#include "executor_pool_basic.h"
-#include "executor_pool_io.h"
-#include "executor_pool_united.h"
-
-namespace NActors {
- LWTRACE_USING(ACTORLIB_PROVIDER);
-
- TCpuManager::TCpuManager(THolder<TActorSystemSetup>& setup)
- : ExecutorPoolCount(setup->GetExecutorsCount())
- , Balancer(setup->Balancer)
- , Config(setup->CpuManager)
- {
- if (setup->Executors) { // Explicit mode w/o united pools
- Executors.Reset(setup->Executors.Release());
- for (ui32 excIdx = 0; excIdx != ExecutorPoolCount; ++excIdx) {
- IExecutorPool* pool = Executors[excIdx].Get();
- Y_ABORT_UNLESS(dynamic_cast<TUnitedExecutorPool*>(pool) == nullptr,
- "united executor pool is prohibited in explicit mode of NActors::TCpuManager");
- }
- } else {
- Setup();
- }
- }
-
- void TCpuManager::Setup() {
- TAffinity available;
- available.Current();
- TCpuAllocationConfig allocation(available, Config);
-
- if (allocation) {
- if (!Balancer) {
- Balancer.Reset(MakeBalancer(Config.UnitedWorkers.Balancer, Config.United, GetCycleCountFast()));
- }
- UnitedWorkers.Reset(new TUnitedWorkers(Config.UnitedWorkers, Config.United, allocation, Balancer.Get()));
- }
-
- ui64 ts = GetCycleCountFast();
- Harmonizer.Reset(MakeHarmonizer(ts));
-
- Executors.Reset(new TAutoPtr<IExecutorPool>[ExecutorPoolCount]);
-
- for (ui32 excIdx = 0; excIdx != ExecutorPoolCount; ++excIdx) {
- Executors[excIdx].Reset(CreateExecutorPool(excIdx));
- if (excIdx < Config.PingInfoByPool.size()) {
- Harmonizer->AddPool(Executors[excIdx].Get(), &Config.PingInfoByPool[excIdx]);
- } else {
- Harmonizer->AddPool(Executors[excIdx].Get());
- }
- }
- }
-
- void TCpuManager::PrepareStart(TVector<NSchedulerQueue::TReader*>& scheduleReaders, TActorSystem* actorSystem) {
- if (UnitedWorkers) {
- UnitedWorkers->Prepare(actorSystem, scheduleReaders);
- }
- for (ui32 excIdx = 0; excIdx != ExecutorPoolCount; ++excIdx) {
- NSchedulerQueue::TReader* readers;
- ui32 readersCount = 0;
- Executors[excIdx]->Prepare(actorSystem, &readers, &readersCount);
- for (ui32 i = 0; i != readersCount; ++i, ++readers) {
- scheduleReaders.push_back(readers);
- }
- }
- }
-
- void TCpuManager::Start() {
- if (UnitedWorkers) {
- UnitedWorkers->Start();
- }
- for (ui32 excIdx = 0; excIdx != ExecutorPoolCount; ++excIdx) {
- Executors[excIdx]->Start();
- }
- }
-
- void TCpuManager::PrepareStop() {
- for (ui32 excIdx = 0; excIdx != ExecutorPoolCount; ++excIdx) {
- Executors[excIdx]->PrepareStop();
- }
- if (UnitedWorkers) {
- UnitedWorkers->PrepareStop();
- }
- }
-
- void TCpuManager::Shutdown() {
- for (ui32 excIdx = 0; excIdx != ExecutorPoolCount; ++excIdx) {
- Executors[excIdx]->Shutdown();
- }
- if (UnitedWorkers) {
- UnitedWorkers->Shutdown();
- }
- for (ui32 round = 0, done = 0; done < ExecutorPoolCount && round < 3; ++round) {
- done = 0;
- for (ui32 excIdx = 0; excIdx != ExecutorPoolCount; ++excIdx) {
- if (Executors[excIdx]->Cleanup()) {
- ++done;
- }
- }
- }
- }
-
- void TCpuManager::Cleanup() {
- for (ui32 round = 0, done = 0; done < ExecutorPoolCount; ++round) {
- Y_ABORT_UNLESS(round < 10, "actorsystem cleanup could not be completed in 10 rounds");
- done = 0;
- for (ui32 excIdx = 0; excIdx != ExecutorPoolCount; ++excIdx) {
- if (Executors[excIdx]->Cleanup()) {
- ++done;
- }
- }
- }
- Executors.Destroy();
- UnitedWorkers.Destroy();
- }
-
- IExecutorPool* TCpuManager::CreateExecutorPool(ui32 poolId) {
- for (TBasicExecutorPoolConfig& cfg : Config.Basic) {
- if (cfg.PoolId == poolId) {
- return new TBasicExecutorPool(cfg, Harmonizer.Get());
- }
- }
- for (TIOExecutorPoolConfig& cfg : Config.IO) {
- if (cfg.PoolId == poolId) {
- return new TIOExecutorPool(cfg);
- }
- }
- for (TUnitedExecutorPoolConfig& cfg : Config.United) {
- if (cfg.PoolId == poolId) {
- IExecutorPool* result = new TUnitedExecutorPool(cfg, UnitedWorkers.Get());
- return result;
- }
- }
- Y_ABORT("missing PoolId: %d", int(poolId));
- }
-
- TVector<IExecutorPool*> TCpuManager::GetBasicExecutorPools() const {
- TVector<IExecutorPool*> pools;
- for (ui32 idx = 0; idx < ExecutorPoolCount; ++idx) {
- if (auto basicPool = dynamic_cast<TBasicExecutorPool*>(Executors[idx].Get()); basicPool != nullptr) {
- pools.push_back(basicPool);
- }
- }
- return pools;
- }
-
-}
diff --git a/library/cpp/actors/core/cpu_manager.h b/library/cpp/actors/core/cpu_manager.h
deleted file mode 100644
index 26ba97aa39..0000000000
--- a/library/cpp/actors/core/cpu_manager.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#pragma once
-
-#include "harmonizer.h"
-#include "executor_pool.h"
-#include "executor_pool_united_workers.h"
-#include "balancer.h"
-
-namespace NActors {
- struct TActorSystemSetup;
-
- class TCpuManager : public TNonCopyable {
- const ui32 ExecutorPoolCount;
- TArrayHolder<TAutoPtr<IExecutorPool>> Executors;
- THolder<TUnitedWorkers> UnitedWorkers;
- THolder<IBalancer> Balancer;
- THolder<IHarmonizer> Harmonizer;
- TCpuManagerConfig Config;
-
- public:
- explicit TCpuManager(THolder<TActorSystemSetup>& setup);
-
- void Setup();
- void PrepareStart(TVector<NSchedulerQueue::TReader*>& scheduleReaders, TActorSystem* actorSystem);
- void Start();
- void PrepareStop();
- void Shutdown();
- void Cleanup();
-
- TVector<IExecutorPool*> GetBasicExecutorPools() const;
-
- ui32 GetExecutorsCount() const {
- return ExecutorPoolCount;
- }
-
- IExecutorPool* GetExecutorPool(ui32 poolId) {
- return Executors[poolId].Get();
- }
-
- void GetPoolStats(ui32 poolId, TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const {
- if (poolId < ExecutorPoolCount) {
- Executors[poolId]->GetCurrentStats(poolStats, statsCopy);
- }
- }
-
- THarmonizerStats GetHarmonizerStats() const {
- if (Harmonizer) {
- return Harmonizer->GetStats();
- }
- return {};
- }
-
- private:
- IExecutorPool* CreateExecutorPool(ui32 poolId);
- };
-}
diff --git a/library/cpp/actors/core/cpu_state.h b/library/cpp/actors/core/cpu_state.h
deleted file mode 100644
index 3f779d5623..0000000000
--- a/library/cpp/actors/core/cpu_state.h
+++ /dev/null
@@ -1,215 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-#include <library/cpp/actors/util/futex.h>
-
-namespace NActors {
-
- class alignas(64) TCpuState {
- // Atomic cachelign-aligned 64-bit state, see description below
- TAtomic State = 0;
- char Padding[64 - sizeof(TAtomic)];
-
- // Bits 0-31: Currently executing pool
- // - value less than MaxPools means cpu is executing corresponding pool (fast-worker is executing or waiting for slow-workers)
- // - one of Cpu* values in case of idle cpu
- // - used as futex by blocked fast-worker
- static constexpr ui64 CurrentBits = 32;
- static constexpr ui64 CurrentMask = ui64((1ull << CurrentBits) - 1);
-
- // Bits 32-63: Assigned pool
- // - value is set by balancer
- // - NOT used as futex
- // - Not balanced
- static constexpr ui64 AssignedOffs = 32;
- static constexpr ui64 AssignedMask = ~CurrentMask;
-
- public:
- TCpuState() {
- Y_UNUSED(Padding);
- }
-
- void Load(TPoolId& assigned, TPoolId& current) const {
- TAtomicBase state = AtomicLoad(&State);
- assigned = (state & AssignedMask) >> AssignedOffs;
- current = state & CurrentMask;
- }
-
- TPoolId CurrentPool() const {
- return TPoolId(AtomicLoad(&State) & CurrentMask);
- }
-
- void SwitchPool(TPoolId pool) {
- while (true) {
- TAtomicBase state = AtomicLoad(&State);
- if (AtomicCas(&State, (state & ~CurrentMask) | pool, state)) {
- return;
- }
- }
- }
-
- TPoolId AssignedPool() const {
- return TPoolId((AtomicLoad(&State) & AssignedMask) >> AssignedOffs);
- }
-
- // Assigns new pool to cpu and wakes it up if cpu is idle
- void AssignPool(TPoolId pool) {
- while (true) {
- TAtomicBase state = AtomicLoad(&State);
- TPoolId current(state & CurrentMask);
- if (Y_UNLIKELY(current == CpuStopped)) {
- return; // it would be better to shutdown instead of balancing
- }
- // Idle cpu must be woken up after balancing to handle pending tokens (if any) in assigned/schedulable pool(s)
- if (current == CpuSpinning) {
- if (AtomicCas(&State, (ui64(pool) << AssignedOffs) | pool, state)) {
- return; // successfully woken up
- }
- } else if (current == CpuBlocked) {
- if (AtomicCas(&State, (ui64(pool) << AssignedOffs) | pool, state)) {
- FutexWake();
- return; // successfully woken up
- }
- } else {
- if (AtomicCas(&State, (ui64(pool) << AssignedOffs) | (state & ~AssignedMask), state)) {
- return; // wakeup is not required
- }
- }
- }
- }
-
- void Stop() {
- while (true) {
- TAtomicBase state = AtomicLoad(&State);
- if (AtomicCas(&State, (state & ~CurrentMask) | CpuStopped, state)) {
- FutexWake();
- return; // successfully stopped
- }
- }
- }
-
- // Start waiting, returns false in case of actorsystem shutdown
- bool StartSpinning() {
- while (true) {
- TAtomicBase state = AtomicLoad(&State);
- TPoolId current(state & CurrentMask);
- if (Y_UNLIKELY(current == CpuStopped)) {
- return false;
- }
- Y_DEBUG_ABORT_UNLESS(current < MaxPools, "unexpected already waiting state of cpu (%d)", (int)current);
- if (AtomicCas(&State, (state & ~CurrentMask) | CpuSpinning, state)) { // successfully marked as spinning
- return true;
- }
- }
- }
-
- bool StartBlocking() {
- while (true) {
- TAtomicBase state = AtomicLoad(&State);
- TPoolId current(state & CurrentMask);
- if (current == CpuSpinning) {
- if (AtomicCas(&State, (state & ~CurrentMask) | CpuBlocked, state)) {
- return false; // successful switch
- }
- } else {
- return true; // wakeup
- }
- }
- }
-
- bool Block(ui64 timeoutNs, TPoolId& result) {
-#ifdef _linux_
- timespec timeout;
- timeout.tv_sec = timeoutNs / 1'000'000'000;
- timeout.tv_nsec = timeoutNs % 1'000'000'000;
- SysFutex(Futex(), FUTEX_WAIT_PRIVATE, CpuBlocked, &timeout, nullptr, 0);
-#else
- NanoSleep(timeoutNs); // non-linux wake is not supported, cpu will go idle on wake after blocked state
-#endif
- TAtomicBase state = AtomicLoad(&State);
- TPoolId current(state & CurrentMask);
- if (current == CpuBlocked) {
- return false; // timeout
- } else {
- result = current;
- return true; // wakeup
- }
- }
-
- enum EWakeResult {
- Woken, // successfully woken up
- NotIdle, // cpu is already not idle
- Forbidden, // cpu is assigned to another pool
- Stopped, // cpu is shutdown
- };
-
- EWakeResult WakeWithoutToken(TPoolId pool) {
- while (true) {
- TAtomicBase state = RelaxedLoad(&State);
- TPoolId current(state & CurrentMask);
- TPoolId assigned((state & AssignedMask) >> AssignedOffs);
- if (assigned == CpuShared || assigned == pool) {
- if (current == CpuSpinning) {
- if (AtomicCas(&State, (state & ~CurrentMask) | pool, state)) {
- return Woken;
- }
- } else if (current == CpuBlocked) {
- if (AtomicCas(&State, (state & ~CurrentMask) | pool, state)) {
- FutexWake();
- return Woken;
- }
- } else if (current == CpuStopped) {
- return Stopped;
- } else {
- return NotIdle;
- }
- } else {
- return Forbidden;
- }
- }
- }
-
- EWakeResult WakeWithTokenAcquired(TPoolId token) {
- while (true) {
- TAtomicBase state = RelaxedLoad(&State);
- TPoolId current(state & CurrentMask);
- // NOTE: We ignore assigned value because we already have token, so
- // NOTE: not assigned pool may be run here. This will be fixed
- // NOTE: after we finish with current activation
- if (current == CpuSpinning) {
- if (AtomicCas(&State, (state & ~CurrentMask) | token, state)) {
- return Woken;
- }
- } else if (current == CpuBlocked) {
- if (AtomicCas(&State, (state & ~CurrentMask) | token, state)) {
- FutexWake();
- return Woken;
- }
- } else if (current == CpuStopped) {
- return Stopped;
- } else {
- return NotIdle;
- }
- }
- }
-
- bool IsPoolReassigned(TPoolId current) const {
- TAtomicBase state = AtomicLoad(&State);
- TPoolId assigned((state & AssignedMask) >> AssignedOffs);
- return assigned != current;
- }
-
- private:
- void* Futex() {
- return (void*)&State; // little endian assumed
- }
-
- void FutexWake() {
-#ifdef _linux_
- SysFutex(Futex(), FUTEX_WAKE_PRIVATE, 1, nullptr, nullptr, 0);
-#endif
- }
- };
-
-}
diff --git a/library/cpp/actors/core/defs.h b/library/cpp/actors/core/defs.h
deleted file mode 100644
index 64b90e995d..0000000000
--- a/library/cpp/actors/core/defs.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#pragma once
-
-// 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>
-
-// Enables collection of
-// event send/receive counts
-// activation time histograms
-// event processing time histograms
-#define ACTORSLIB_COLLECT_EXEC_STATS
-
-static constexpr bool ActorLibCollectUsageStats = false;
-
-namespace NActors {
- using TPoolId = ui8;
- using TPoolsMask = ui64;
- 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
- static constexpr TPoolId CpuStopped = TPoolId(-1); // special value indicating worker should stop
- static constexpr TPoolId CpuShared = MaxPools; // special value for `assigned` meaning balancer disabled, pool scheduler is used instead
-
- using TPoolWeight = ui16;
- static constexpr TPoolWeight MinPoolWeight = 1;
- static constexpr TPoolWeight DefPoolWeight = 32;
- static constexpr TPoolWeight MaxPoolWeight = 1024;
-
- using TWorkerId = i16;
- static constexpr TWorkerId WorkerBits = 11;
- static constexpr TWorkerId MaxWorkers = 1 << WorkerBits;
-
- using TThreadId = ui64;
- static constexpr TThreadId UnknownThreadId = ui64(-1);
-
- struct TMailboxType {
- enum EType {
- Inherited = -1, // inherit mailbox from parent
- Simple = 0, // simplest queue under producer lock. fastest in no-contention case
- Revolving = 1, // somewhat outdated, tries to be wait-free. replaced by ReadAsFilled
- HTSwap = 2, // other simple lf queue, suggested for low-contention case
- ReadAsFilled = 3, // wait-free queue, suggested for high-contention or latency critical
- TinyReadAsFilled = 4, // same as 3 but with lower overhead
- //Inplace;
- //Direct;
- //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);
- }
-
- enum class ESendingType {
- Common,
- Lazy,
- Tail,
- };
-
-}
-
-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
deleted file mode 100644
index 6ffe42f65b..0000000000
--- a/library/cpp/actors/core/event.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "event.h"
-#include "event_pb.h"
-
-namespace NActors {
-
- const TScopeId TScopeId::LocallyGenerated{
- Max<ui64>(), Max<ui64>()
- };
-
- TString IEventHandle::GetTypeName() const {
- return HasEvent() ? TypeName(*(const_cast<IEventHandle*>(this)->GetBase())) : TypeName(*this);
- }
-
- TString IEventHandle::ToString() const {
- return HasEvent() ? const_cast<IEventHandle*>(this)->GetBase()->ToString().data() : "serialized?";
- }
-
- std::unique_ptr<IEventHandle> IEventHandle::Forward(std::unique_ptr<IEventHandle>&& ev, TActorId recipient) {
- return std::unique_ptr<IEventHandle>(ev->Forward(recipient).Release());
- }
-
- TIntrusivePtr<TEventSerializedData> IEventHandle::ReleaseChainBuffer() {
- if (Buffer) {
- TIntrusivePtr<TEventSerializedData> result;
- DoSwap(result, Buffer);
- Event.Reset();
- return result;
- }
- if (Event) {
- TAllocChunkSerializer serializer;
- Event->SerializeToArcadiaStream(&serializer);
- auto chainBuf = serializer.Release(Event->CreateSerializationInfo());
- Event.Reset();
- return chainBuf;
- }
- return new TEventSerializedData;
- }
-
- TIntrusivePtr<TEventSerializedData> IEventHandle::GetChainBuffer() {
- if (Buffer) {
- return Buffer;
- }
- if (Event) {
- TAllocChunkSerializer serializer;
- Event->SerializeToArcadiaStream(&serializer);
- Buffer = serializer.Release(Event->CreateSerializationInfo());
- return Buffer;
- }
- return new TEventSerializedData;
- }
-}
diff --git a/library/cpp/actors/core/event.h b/library/cpp/actors/core/event.h
deleted file mode 100644
index 3517dc7a68..0000000000
--- a/library/cpp/actors/core/event.h
+++ /dev/null
@@ -1,389 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include "actorid.h"
-#include "callstack.h"
-#include "event_load.h"
-
-#include <library/cpp/actors/wilson/wilson_trace.h>
-
-#include <util/system/hp_timer.h>
-#include <util/generic/maybe.h>
-
-namespace NActors {
- class TChunkSerializer;
- class IActor;
- class ISerializerToStream {
- public:
- virtual bool SerializeToArcadiaStream(TChunkSerializer*) const = 0;
- };
-
- class IEventBase
- : TNonCopyable,
- public ISerializerToStream {
- protected:
- // for compatibility with virtual actors
- virtual bool DoExecute(IActor* /*actor*/, std::unique_ptr<IEventHandle> /*eventPtr*/) {
- Y_DEBUG_ABORT_UNLESS(false);
- return false;
- }
- public:
- // actual typing is performed by IEventHandle
-
- virtual ~IEventBase() {
- }
-
- bool Execute(IActor* actor, std::unique_ptr<IEventHandle> eventPtr) {
- return DoExecute(actor, std::move(eventPtr));
- }
-
- virtual TString ToStringHeader() const = 0;
- virtual TString ToString() const {
- return ToStringHeader();
- }
- virtual ui32 CalculateSerializedSize() const {
- return 0;
- }
- virtual ui32 Type() const = 0;
- virtual bool SerializeToArcadiaStream(TChunkSerializer*) const = 0;
- virtual bool IsSerializable() const = 0;
- virtual ui32 CalculateSerializedSizeCached() const {
- return CalculateSerializedSize();
- }
- virtual TEventSerializationInfo CreateSerializationInfo() const { return {}; }
- };
-
- // fat handle
- class IEventHandle : TNonCopyable {
- struct TOnNondelivery {
- TActorId Recipient;
-
- TOnNondelivery(const TActorId& recipient)
- : Recipient(recipient)
- {
- }
- };
-
- public:
- template <typename TEv>
- inline TEv* CastAsLocal() const noexcept {
- auto fits = GetTypeRewrite() == TEv::EventType;
-
- return fits ? static_cast<TEv*>(Event.Get()) : nullptr;
- }
-
- template <typename TEventType>
- TEventType* Get() {
- if (Type != TEventType::EventType)
- Y_ABORT("Event type %" PRIu32 " doesn't match the expected type %" PRIu32, Type, TEventType::EventType);
-
- if (!Event) {
- static TEventSerializedData empty;
- Event.Reset(TEventType::Load(Buffer ? Buffer.Get() : &empty));
- }
-
- if (Event) {
- return static_cast<TEventType*>(Event.Get());
- }
-
- Y_ABORT("Failed to Load() event type %" PRIu32 " class %s", Type, TypeName<TEventType>().data());
- }
-
- template <typename T>
- TAutoPtr<T> Release() {
- TAutoPtr<T> x = Get<T>();
- Y_UNUSED(Event.Release());
- Buffer.Reset();
- return x;
- }
-
- enum EFlags: ui32 {
- FlagTrackDelivery = 1 << 0,
- FlagForwardOnNondelivery = 1 << 1,
- FlagSubscribeOnSession = 1 << 2,
- FlagUseSubChannel = 1 << 3,
- FlagGenerateUnsureUndelivered = 1 << 4,
- FlagExtendedFormat = 1 << 5,
- };
- using TEventFlags = ui32;
-
- const ui32 Type;
- const TEventFlags Flags;
- const TActorId Recipient;
- TActorId Sender;
- const ui64 Cookie;
- 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;
-
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- ::NHPTimer::STime SendTime;
-#endif
-
- static const size_t ChannelBits = 12;
- static const size_t ChannelShift = (sizeof(ui32) << 3) - ChannelBits;
-
-#ifdef USE_ACTOR_CALLSTACK
- TCallstack Callstack;
-#endif
- ui16 GetChannel() const noexcept {
- return Flags >> ChannelShift;
- }
-
- ui64 GetSubChannel() const noexcept {
- return Flags & FlagUseSubChannel ? Sender.LocalId() : 0ULL;
- }
-
- static ui32 MakeFlags(ui32 channel, TEventFlags flags) {
- Y_ABORT_UNLESS(channel < (1 << ChannelBits));
- Y_ABORT_UNLESS(flags < (1 << ChannelShift));
- return (flags | (channel << ChannelShift));
- }
-
- private:
- THolder<IEventBase> Event;
- TIntrusivePtr<TEventSerializedData> Buffer;
-
- TActorId RewriteRecipient;
- ui32 RewriteType;
-
- THolder<TOnNondelivery> OnNondeliveryHolder; // only for local events
-
- public:
- void Rewrite(ui32 typeRewrite, TActorId recipientRewrite) {
- RewriteRecipient = recipientRewrite;
- RewriteType = typeRewrite;
- }
-
- void DropRewrite() {
- RewriteRecipient = Recipient;
- RewriteType = Type;
- }
-
- const TActorId& GetRecipientRewrite() const {
- return RewriteRecipient;
- }
-
- ui32 GetTypeRewrite() const {
- return RewriteType;
- }
-
- TActorId GetForwardOnNondeliveryRecipient() const {
- return OnNondeliveryHolder.Get() ? OnNondeliveryHolder->Recipient : TActorId();
- }
-
- IEventHandle(const TActorId& recipient, const TActorId& sender, IEventBase* ev, TEventFlags flags = 0, ui64 cookie = 0,
- const TActorId* forwardOnNondelivery = nullptr, NWilson::TTraceId traceId = {})
- : Type(ev->Type())
- , Flags(flags)
- , Recipient(recipient)
- , Sender(sender)
- , Cookie(cookie)
- , TraceId(std::move(traceId))
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- , SendTime(0)
-#endif
- , Event(ev)
- , RewriteRecipient(Recipient)
- , RewriteType(Type)
- {
- if (forwardOnNondelivery)
- OnNondeliveryHolder.Reset(new TOnNondelivery(*forwardOnNondelivery));
- }
-
- IEventHandle(ui32 type,
- TEventFlags flags,
- const TActorId& recipient,
- const TActorId& sender,
- TIntrusivePtr<TEventSerializedData> buffer,
- ui64 cookie,
- const TActorId* forwardOnNondelivery = nullptr,
- NWilson::TTraceId traceId = {})
- : Type(type)
- , Flags(flags)
- , Recipient(recipient)
- , Sender(sender)
- , Cookie(cookie)
- , TraceId(std::move(traceId))
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- , SendTime(0)
-#endif
- , Buffer(std::move(buffer))
- , RewriteRecipient(Recipient)
- , RewriteType(Type)
- {
- if (forwardOnNondelivery)
- OnNondeliveryHolder.Reset(new TOnNondelivery(*forwardOnNondelivery));
- }
-
- // Special ctor for events from interconnect.
- IEventHandle(const TActorId& session,
- ui32 type,
- TEventFlags flags,
- const TActorId& recipient,
- const TActorId& sender,
- TIntrusivePtr<TEventSerializedData> buffer,
- ui64 cookie,
- TScopeId originScopeId,
- NWilson::TTraceId traceId) noexcept
- : Type(type)
- , Flags(flags)
- , Recipient(recipient)
- , Sender(sender)
- , Cookie(cookie)
- , OriginScopeId(originScopeId)
- , TraceId(std::move(traceId))
- , InterconnectSession(session)
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- , SendTime(0)
-#endif
- , Buffer(std::move(buffer))
- , RewriteRecipient(Recipient)
- , RewriteType(Type)
- {
- }
-
- TIntrusivePtr<TEventSerializedData> GetChainBuffer();
- TIntrusivePtr<TEventSerializedData> ReleaseChainBuffer();
-
- ui32 GetSize() const {
- if (Buffer) {
- return Buffer->GetSize();
- } else if (Event) {
- return Event->CalculateSerializedSize();
- } else {
- return 0;
- }
- }
-
- bool HasBuffer() const {
- return bool(Buffer);
- }
-
- bool HasEvent() const {
- return bool(Event);
- }
-
- IEventBase* GetBase() {
- if (!Event) {
- if (!Buffer)
- return nullptr;
- else
- ythrow TWithBackTrace<yexception>() << "don't know how to load the event from buffer";
- }
-
- return Event.Get();
- }
-
- TAutoPtr<IEventBase> ReleaseBase() {
- TAutoPtr<IEventBase> x = GetBase();
- Y_UNUSED(Event.Release());
- Buffer.Reset();
- return x;
- }
-
- TAutoPtr<IEventHandle> Forward(const TActorId& dest) {
- if (Event)
- return new IEventHandle(dest, Sender, Event.Release(), Flags, Cookie, nullptr, std::move(TraceId));
- else
- return new IEventHandle(Type, Flags, dest, Sender, Buffer, Cookie, nullptr, std::move(TraceId));
- }
-
- TString GetTypeName() const;
- TString ToString() const;
-
- [[nodiscard]] static std::unique_ptr<IEventHandle> Forward(std::unique_ptr<IEventHandle>&& ev, TActorId recipient);
- [[nodiscard]] static std::unique_ptr<IEventHandle> ForwardOnNondelivery(std::unique_ptr<IEventHandle>&& ev, ui32 reason, bool unsure = false);
-
- [[nodiscard]] static TAutoPtr<IEventHandle> Forward(TAutoPtr<IEventHandle>&& ev, TActorId recipient) {
- return Forward(std::unique_ptr<IEventHandle>(ev.Release()), recipient).release();
- }
-
- [[nodiscard]] static THolder<IEventHandle> Forward(THolder<IEventHandle>&& ev, TActorId recipient) {
- return THolder(Forward(std::unique_ptr<IEventHandle>(ev.Release()), recipient).release());
- }
-
- [[nodiscard]] static TAutoPtr<IEventHandle> ForwardOnNondelivery(TAutoPtr<IEventHandle>&& ev, ui32 reason, bool unsure = false) {
- return ForwardOnNondelivery(std::unique_ptr<IEventHandle>(ev.Release()), reason, unsure).release();
- }
-
- [[nodiscard]] static THolder<IEventHandle> ForwardOnNondelivery(THolder<IEventHandle>&& ev, ui32 reason, bool unsure = false) {
- return THolder(ForwardOnNondelivery(std::unique_ptr<IEventHandle>(ev.Release()), reason, unsure).release());
- }
-
- template<typename T>
- static TAutoPtr<T> Release(TAutoPtr<IEventHandle>& ev) {
- return ev->Release<T>();
- }
-
- template<typename T>
- static TAutoPtr<T> Release(THolder<IEventHandle>& ev) {
- return ev->Release<T>();
- }
-
- template <typename TEv>
- inline TEv* StaticCastAsLocal() const noexcept { // blind cast
- return static_cast<TEv*>(Event.Get());
- }
- };
-
- template <typename TEventType>
- class TEventHandle: public IEventHandle {
- TEventHandle(); // we never made instance of TEventHandle
- public:
- TEventType* Get() {
- return IEventHandle::Get<TEventType>();
- }
-
- TAutoPtr<TEventType> Release() {
- return IEventHandle::Release<TEventType>();
- }
- };
-
- static_assert(sizeof(TEventHandle<IEventBase>) == sizeof(IEventHandle), "expect sizeof(TEventHandle<IEventBase>) == sizeof(IEventHandle)");
-
- template <typename TEventType, ui32 EventType0>
- class TEventBase: public IEventBase {
- public:
- static constexpr ui32 EventType = EventType0;
- ui32 Type() const override {
- return EventType0;
- }
- // still abstract
-
- typedef TEventHandle<TEventType> THandle;
- typedef TAutoPtr<THandle> TPtr;
- };
-
-#define DEFINE_SIMPLE_LOCAL_EVENT(eventType, header) \
- TString ToStringHeader() const override { \
- return TString(header); \
- } \
- bool SerializeToArcadiaStream(NActors::TChunkSerializer*) const override { \
- Y_ABORT("Local event " #eventType " is not serializable"); \
- } \
- static IEventBase* Load(NActors::TEventSerializedData*) { \
- Y_ABORT("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); \
- } \
- bool SerializeToArcadiaStream(NActors::TChunkSerializer*) const override { \
- 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.cpp b/library/cpp/actors/core/event_load.cpp
deleted file mode 100644
index 2171678bfb..0000000000
--- a/library/cpp/actors/core/event_load.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "event_load.h"
-
-namespace NActors {
-
-}
diff --git a/library/cpp/actors/core/event_load.h b/library/cpp/actors/core/event_load.h
deleted file mode 100644
index c776026cc4..0000000000
--- a/library/cpp/actors/core/event_load.h
+++ /dev/null
@@ -1,133 +0,0 @@
-#pragma once
-
-#include <util/stream/walk.h>
-#include <util/system/types.h>
-#include <util/generic/string.h>
-#include <library/cpp/actors/util/rope.h>
-#include <library/cpp/actors/wilson/wilson_trace.h>
-
-namespace NActors {
- class IEventHandle;
-
- struct TConstIoVec {
- const void* Data;
- size_t Size;
- };
-
- struct TIoVec {
- void* Data;
- size_t Size;
- };
-
- struct TEventSectionInfo {
- size_t Headroom = 0; // headroom to be created on the receiving side
- size_t Size = 0; // full size of serialized event section (a chunk in rope)
- size_t Tailroom = 0; // tailroom for the chunk
- size_t Alignment = 0; // required alignment
- bool IsInline = false; // if true, goes through ordinary channel
- };
-
- struct TEventSerializationInfo {
- bool IsExtendedFormat = {};
- std::vector<TEventSectionInfo> Sections;
- // total sum of Size for every section must match actual serialized size of the event
- };
-
- class TEventSerializedData
- : public TThrRefBase
- {
- TRope Rope;
- TEventSerializationInfo SerializationInfo;
-
- public:
- TEventSerializedData() = default;
-
- TEventSerializedData(TRope&& rope, TEventSerializationInfo&& serializationInfo)
- : Rope(std::move(rope))
- , SerializationInfo(std::move(serializationInfo))
- {}
-
- TEventSerializedData(const TEventSerializedData& original, TString extraBuffer)
- : Rope(original.Rope)
- , SerializationInfo(original.SerializationInfo)
- {
- if (!SerializationInfo.Sections.empty()) {
- SerializationInfo.Sections.push_back(TEventSectionInfo{0, extraBuffer.size(), 0, 0, true});
- }
- Append(std::move(extraBuffer));
- }
-
- TEventSerializedData(TString buffer, TEventSerializationInfo&& serializationInfo)
- : SerializationInfo(std::move(serializationInfo))
- {
- Append(std::move(buffer));
- }
-
- void SetSerializationInfo(TEventSerializationInfo&& serializationInfo) {
- SerializationInfo = std::move(serializationInfo);
- }
-
- const TEventSerializationInfo& GetSerializationInfo() const {
- return SerializationInfo;
- }
-
- 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 GetRope() const {
- return TRope(Rope);
- }
-
- TRope EraseBack(size_t count) {
- Y_ABORT_UNLESS(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(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;
- }
-};
diff --git a/library/cpp/actors/core/event_local.h b/library/cpp/actors/core/event_local.h
deleted file mode 100644
index da0f740ba8..0000000000
--- a/library/cpp/actors/core/event_local.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#pragma once
-
-#include "event.h"
-#include "scheduler_cookie.h"
-#include "event_load.h"
-#include <util/system/type_name.h>
-
-namespace NActors {
- template <typename TEv, ui32 TEventType>
- class TEventLocal: public TEventBase<TEv, TEventType> {
- public:
- TString ToStringHeader() const override {
- return TypeName<TEv>();
- }
-
- bool SerializeToArcadiaStream(TChunkSerializer* /*serializer*/) const override {
- Y_ABORT("Serialization of local event %s type %" PRIu32, TypeName<TEv>().data(), TEventType);
- }
-
- bool IsSerializable() const override {
- return false;
- }
-
- static IEventBase* Load(TEventSerializedData*) {
- Y_ABORT("Loading of local event %s type %" PRIu32, TypeName<TEv>().data(), TEventType);
- }
- };
-
- template <typename TEv, ui32 TEventType>
- class TEventScheduler: public TEventLocal<TEv, TEventType> {
- public:
- TSchedulerCookieHolder Cookie;
-
- TEventScheduler(ISchedulerCookie* cookie)
- : Cookie(cookie)
- {
- }
- };
-
- template <ui32 TEventType>
- class TEventSchedulerEv: public TEventScheduler<TEventSchedulerEv<TEventType>, TEventType> {
- public:
- TEventSchedulerEv(ISchedulerCookie* cookie)
- : TEventScheduler<TEventSchedulerEv<TEventType>, TEventType>(cookie)
- {
- }
- };
-
- template <typename TEv, ui32 TEventType>
- class TEventSimple: public TEventBase<TEv, TEventType> {
- public:
- TString ToStringHeader() const override {
- static TString header(TypeName<TEv>());
- return header;
- }
-
- 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 IEventBase* Load(NActors::TEventSerializedData*) {
- return new TEv();
- }
-
- static IEventBase* Load(const TString&) {
- return new TEv();
- }
- };
-}
diff --git a/library/cpp/actors/core/event_pb.cpp b/library/cpp/actors/core/event_pb.cpp
deleted file mode 100644
index e6a863c44e..0000000000
--- a/library/cpp/actors/core/event_pb.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-#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();
- }
- TotalByteCount += *size;
- return *size != 0;
- }
-
- void TRopeStream::BackUp(int count) {
- Y_ABORT_UNLESS(count <= TotalByteCount);
- Iter -= count;
- TotalByteCount -= count;
- }
-
- 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;
- }
-
- TCoroutineChunkSerializer::TCoroutineChunkSerializer()
- : TotalSerializedDataSize(0)
- , Stack(64 * 1024)
- , SelfClosure{this, TArrayRef(Stack.Begin(), Stack.End())}
- , InnerContext(SelfClosure)
- {}
-
- TCoroutineChunkSerializer::~TCoroutineChunkSerializer() {
- CancelFlag = true;
- Resume();
- Y_ABORT_UNLESS(Finished);
- }
-
- bool TCoroutineChunkSerializer::AllowsAliasing() const {
- return true;
- }
-
- void TCoroutineChunkSerializer::Produce(const void *data, size_t size) {
- Y_ABORT_UNLESS(size <= SizeRemain);
- SizeRemain -= size;
- TotalSerializedDataSize += size;
-
- if (!Chunks.empty()) {
- auto& last = Chunks.back();
- if (last.first + last.second == data) {
- last.second += size; // just extend the last buffer
- return;
- }
- }
-
- Chunks.emplace_back(static_cast<const char*>(data), size);
- }
-
- bool TCoroutineChunkSerializer::WriteAliasedRaw(const void* data, int size) {
- Y_ABORT_UNLESS(!CancelFlag);
- Y_ABORT_UNLESS(!AbortFlag);
- Y_ABORT_UNLESS(size >= 0);
- while (size) {
- if (const size_t bytesToAppend = Min<size_t>(size, SizeRemain)) {
- const void *produce = data;
- if ((reinterpret_cast<uintptr_t>(data) & 63) + bytesToAppend <= 64 &&
- (Chunks.empty() || data != Chunks.back().first + Chunks.back().second)) {
- memcpy(BufferPtr, data, bytesToAppend);
- produce = BufferPtr;
- BufferPtr += bytesToAppend;
- }
- Produce(produce, bytesToAppend);
- data = static_cast<const char*>(data) + bytesToAppend;
- size -= bytesToAppend;
- } else {
- InnerContext.SwitchTo(BufFeedContext);
- if (CancelFlag || AbortFlag) {
- return false;
- }
- }
- }
- return true;
- }
-
- bool TCoroutineChunkSerializer::Next(void** data, int* size) {
- Y_ABORT_UNLESS(!CancelFlag);
- Y_ABORT_UNLESS(!AbortFlag);
- if (!SizeRemain) {
- InnerContext.SwitchTo(BufFeedContext);
- if (CancelFlag || AbortFlag) {
- return false;
- }
- }
- Y_ABORT_UNLESS(SizeRemain);
- *data = BufferPtr;
- *size = SizeRemain;
- BufferPtr += SizeRemain;
- Produce(*data, *size);
- return true;
- }
-
- void TCoroutineChunkSerializer::BackUp(int count) {
- if (!count) {
- return;
- }
- Y_ABORT_UNLESS(count > 0);
- Y_ABORT_UNLESS(!Chunks.empty());
- TChunk& buf = Chunks.back();
- Y_ABORT_UNLESS((size_t)count <= buf.second);
- Y_ABORT_UNLESS(buf.first + buf.second == BufferPtr, "buf# %p:%zu BufferPtr# %p SizeRemain# %zu NumChunks# %zu",
- buf.first, buf.second, BufferPtr, SizeRemain, Chunks.size());
- buf.second -= count;
- if (!buf.second) {
- Chunks.pop_back();
- }
- BufferPtr -= count;
- SizeRemain += count;
- TotalSerializedDataSize -= count;
- }
-
- void TCoroutineChunkSerializer::Resume() {
- 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::span<TCoroutineChunkSerializer::TChunk> TCoroutineChunkSerializer::FeedBuf(void* data, size_t size) {
- // fill in base params
- BufferPtr = static_cast<char*>(data);
- SizeRemain = size;
- Y_DEBUG_ABORT_UNLESS(size);
-
- // transfer control to the coroutine
- Y_ABORT_UNLESS(Event);
- Chunks.clear();
- Resume();
-
- return Chunks;
- }
-
- void TCoroutineChunkSerializer::SetSerializingEvent(const IEventBase *event) {
- Y_ABORT_UNLESS(Event == nullptr);
- Event = event;
- TotalSerializedDataSize = 0;
- AbortFlag = false;
- }
-
- void TCoroutineChunkSerializer::Abort() {
- Y_ABORT_UNLESS(Event);
- AbortFlag = true;
- Resume();
- }
-
- void TCoroutineChunkSerializer::DoRun() {
- while (!CancelFlag) {
- Y_ABORT_UNLESS(Event);
- SerializationSuccess = !AbortFlag && Event->SerializeToArcadiaStream(this);
- Event = nullptr;
- if (!CancelFlag) { // cancel flag may have been received during serialization
- 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)));
- }
- return true;
- }
-
- void TAllocChunkSerializer::BackUp(int count) {
- Backup.Insert(Backup.Begin(), Buffers->EraseBack(count));
- }
-
- bool TAllocChunkSerializer::WriteAliasedRaw(const void*, int) {
- Y_ABORT_UNLESS(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;
- }
-}
diff --git a/library/cpp/actors/core/event_pb.h b/library/cpp/actors/core/event_pb.h
deleted file mode 100644
index 5fce7c830f..0000000000
--- a/library/cpp/actors/core/event_pb.h
+++ /dev/null
@@ -1,654 +0,0 @@
-#pragma once
-
-#include "event.h"
-#include "event_load.h"
-
-#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/arena.h>
-#include <library/cpp/actors/protos/actors.pb.h>
-#include <library/cpp/containers/stack_vector/stack_vec.h>
-#include <util/generic/deque.h>
-#include <util/system/context.h>
-#include <util/system/filemap.h>
-#include <util/string/builder.h>
-#include <util/thread/lfstack.h>
-#include <array>
-#include <span>
-
-// enable only when patch with this macro was successfully deployed
-#define USE_EXTENDED_PAYLOAD_FORMAT 0
-
-namespace NActors {
-
- 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;
- int64_t ByteCount() const override {
- return TotalByteCount;
- }
-
- private:
- int64_t TotalByteCount = 0;
- };
-
- 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;
- };
-
- class TAllocChunkSerializer final : public TChunkSerializer {
- public:
- 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;
-
- // 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(TEventSerializationInfo&& serializationInfo) {
- Buffers->SetSerializationInfo(std::move(serializationInfo));
- return std::move(Buffers);
- }
-
- protected:
- TIntrusivePtr<TEventSerializedData> Buffers = new TEventSerializedData;
- TRope Backup;
- };
-
- class TCoroutineChunkSerializer final : public TChunkSerializer, protected ITrampoLine {
- public:
- using TChunk = std::pair<const char*, size_t>;
-
- TCoroutineChunkSerializer();
- ~TCoroutineChunkSerializer();
-
- void SetSerializingEvent(const IEventBase *event);
- void Abort();
- std::span<TChunk> FeedBuf(void* data, size_t size);
- bool IsComplete() const {
- return !Event;
- }
- bool IsSuccessfull() const {
- return SerializationSuccess;
- }
- const IEventBase *GetCurrentEvent() const {
- return Event;
- }
-
- bool Next(void** data, int* size) override;
- void BackUp(int count) override;
- int64_t ByteCount() const override {
- return TotalSerializedDataSize;
- }
- bool WriteAliasedRaw(const void* data, int size) override;
- bool AllowsAliasing() const override;
-
- bool WriteRope(const TRope *rope) override;
- bool WriteString(const TString *s) override;
-
- protected:
- void DoRun() override;
- void Resume();
- void Produce(const void *data, size_t size);
-
- i64 TotalSerializedDataSize;
- TMappedAllocation Stack;
- TContClosure SelfClosure;
- TContMachineContext InnerContext;
- TContMachineContext *BufFeedContext = nullptr;
- char *BufferPtr;
- size_t SizeRemain;
- std::vector<TChunk> Chunks;
- const IEventBase *Event = nullptr;
- bool CancelFlag = false;
- bool AbortFlag;
- bool SerializationSuccess;
- bool Finished = false;
- };
-
- struct TProtoArenaHolder : public TAtomicRefCount<TProtoArenaHolder> {
- google::protobuf::Arena Arena;
- TProtoArenaHolder() = default;
-
- explicit TProtoArenaHolder(const google::protobuf::ArenaOptions& arenaOptions)
- : Arena(arenaOptions)
- {};
-
- google::protobuf::Arena* Get() {
- return &Arena;
- }
-
- template<typename TRecord>
- TRecord* Allocate() {
- return google::protobuf::Arena::CreateMessage<TRecord>(&Arena);
- }
- };
-
- static const size_t EventMaxByteSize = 140 << 20; // (140MB)
-
- 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;
- size_t TotalPayloadSize = 0;
-
- public:
- using TRecHolder::Record;
-
- public:
- using ProtoRecordType = TRecord;
-
- TEventPBBase() = default;
-
- explicit TEventPBBase(const TRecord& rec)
- : TRecHolder(rec)
- {}
-
- explicit TEventPBBase(TRecord&& rec)
- : TRecHolder(rec)
- {}
-
- explicit TEventPBBase(TIntrusivePtr<TProtoArenaHolder> arena)
- : TRecHolder(std::move(arena))
- {}
-
- TString ToStringHeader() const override {
- return Record.GetTypeName();
- }
-
- TString ToString() const override {
- TStringStream ss;
- ss << ToStringHeader() << " " << Record.ShortDebugString();
- return ss.Str();
- }
-
- bool IsSerializable() const override {
- return true;
- }
-
- bool SerializeToArcadiaStream(TChunkSerializer* chunker) const override {
- return SerializeToArcadiaStreamImpl(chunker, TString());
- }
-
- 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 += TotalPayloadSize;
- }
- return result;
- }
-
- static IEventBase* Load(TEventSerializedData *input) {
- THolder<TEventPBBase> ev(new TEv());
- if (!input->GetSize()) {
- Y_PROTOBUF_SUPPRESS_NODISCARD ev->Record.ParseFromString(TString());
- } else {
- TRope::TConstIterator iter = input->GetBeginIter();
- ui64 size = input->GetSize();
-
- if (const auto& info = input->GetSerializationInfo(); info.IsExtendedFormat) {
- // check marker
- if (!iter.Valid() || (*iter.ContiguousData() != PayloadMarker && *iter.ContiguousData() != ExtendedPayloadMarker)) {
- Y_ABORT("invalid event");
- }
-
- const bool dataIsSeparate = *iter.ContiguousData() == ExtendedPayloadMarker; // ropes go after sizes
-
- auto fetchRope = [&](size_t len) {
- TRope::TConstIterator begin = iter;
- iter += len;
- size -= len;
- ev->Payload.emplace_back(begin, iter);
- ev->TotalPayloadSize += len;
- };
-
- // skip marker
- iter += 1;
- --size;
- // parse number of payload ropes
- size_t numRopes = DeserializeNumber(iter, size);
- if (numRopes == Max<size_t>()) {
- Y_ABORT("invalid event");
- }
- TStackVec<size_t, 16> ropeLens;
- if (dataIsSeparate) {
- ropeLens.reserve(numRopes);
- }
- while (numRopes--) {
- // parse length of the rope
- const size_t len = DeserializeNumber(iter, size);
- if (len == Max<size_t>() || size < len) {
- Y_ABORT("invalid event len# %zu size# %" PRIu64, len, size);
- }
- // extract the rope
- if (dataIsSeparate) {
- ropeLens.push_back(len);
- } else {
- fetchRope(len);
- }
- }
- for (size_t len : ropeLens) {
- fetchRope(len);
- }
- }
-
- // parse the protobuf
- TRopeStream stream(iter, size);
- if (!ev->Record.ParseFromZeroCopyStream(&stream)) {
- Y_ABORT("Failed to parse protobuf event type %" PRIu32 " class %s", TEventType, TypeName(ev->Record).data());
- }
- }
- ev->CachedByteSize = input->GetSize();
- return ev.Release();
- }
-
- size_t GetCachedByteSize() const {
- if (CachedByteSize == 0) {
- CachedByteSize = CalculateSerializedSize();
- }
- return CachedByteSize;
- }
-
- ui32 CalculateSerializedSizeCached() const override {
- return GetCachedByteSize();
- }
-
- void InvalidateCachedByteSize() {
- CachedByteSize = 0;
- }
-
- TEventSerializationInfo CreateSerializationInfo() const override {
- return CreateSerializationInfoImpl(0);
- }
-
- bool AllowExternalDataChannel() const {
- return TotalPayloadSize >= 4096;
- }
-
- public:
- void ReservePayload(size_t size) {
- Payload.reserve(size);
- }
-
- ui32 AddPayload(TRope&& rope) {
- const ui32 id = Payload.size();
- TotalPayloadSize += rope.size();
- Payload.push_back(std::move(rope));
- InvalidateCachedByteSize();
- return id;
- }
-
- const TRope& GetPayload(ui32 id) const {
- Y_ABORT_UNLESS(id < Payload.size());
- return Payload[id];
- }
-
- ui32 GetPayloadCount() const {
- return Payload.size();
- }
-
- void StripPayload() {
- Payload.clear();
- TotalPayloadSize = 0;
- }
-
- protected:
- TEventSerializationInfo CreateSerializationInfoImpl(size_t preserializedSize) const {
- TEventSerializationInfo info;
- info.IsExtendedFormat = static_cast<bool>(Payload);
-
- if (static_cast<const TEv&>(*this).AllowExternalDataChannel()) {
- if (Payload) {
- char temp[MaxNumberBytes];
-#if USE_EXTENDED_PAYLOAD_FORMAT
- size_t headerLen = 1 + SerializeNumber(Payload.size(), temp);
- for (const TRope& rope : Payload) {
- headerLen += SerializeNumber(rope.size(), temp);
- }
- info.Sections.push_back(TEventSectionInfo{0, headerLen, 0, 0, true});
- for (const TRope& rope : Payload) {
- info.Sections.push_back(TEventSectionInfo{0, rope.size(), 0, 0, false});
- }
-#else
- info.Sections.push_back(TEventSectionInfo{0, 1 + SerializeNumber(Payload.size(), temp), 0, 0, true}); // payload marker and rope count
- for (const TRope& rope : Payload) {
- const size_t ropeSize = rope.GetSize();
- info.Sections.back().Size += SerializeNumber(ropeSize, temp);
- info.Sections.push_back(TEventSectionInfo{0, ropeSize, 0, 0, false}); // data as a separate section
- }
-#endif
- }
-
- const size_t byteSize = Max<ssize_t>(0, Record.ByteSize()) + preserializedSize;
- info.Sections.push_back(TEventSectionInfo{0, byteSize, 0, 0, true}); // protobuf itself
-
-#ifndef NDEBUG
- size_t total = 0;
- for (const auto& section : info.Sections) {
- total += section.Size;
- }
- size_t serialized = CalculateSerializedSize();
- Y_ABORT_UNLESS(total == serialized, "total# %zu serialized# %zu byteSize# %zd Payload.size# %zu", total,
- serialized, byteSize, Payload.size());
-#endif
- }
-
- return info;
- }
-
- bool SerializeToArcadiaStreamImpl(TChunkSerializer* chunker, const TString& preserialized) const {
- // 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));
- };
-
-#if USE_EXTENDED_PAYLOAD_FORMAT
- char marker = ExtendedPayloadMarker;
- append(&marker, 1);
- if (!appendNumber(Payload.size())) {
- return false;
- }
- for (const TRope& rope : Payload) {
- if (!appendNumber(rope.GetSize())) {
- return false;
- }
- }
- if (size) {
- chunker->BackUp(std::exchange(size, 0));
- }
- for (const TRope& rope : Payload) {
- if (!chunker->WriteRope(&rope)) {
- return false;
- }
- }
-#else
- 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);
- }
-#endif
- }
-
- if (preserialized && !chunker->WriteString(&preserialized)) {
- return false;
- }
-
- return Record.SerializeToZeroCopyStream(chunker);
- }
-
- protected:
- mutable size_t CachedByteSize = 0;
-
- static constexpr char ExtendedPayloadMarker = 0x06;
- 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
- template <typename TRecord>
- struct TRecordHolder {
- TRecord Record;
-
- TRecordHolder() = default;
- TRecordHolder(const TRecord& rec)
- : Record(rec)
- {}
-
- TRecordHolder(TRecord&& rec)
- : Record(std::move(rec))
- {}
- };
-
- // Protobuf arena and a record allocated on it
- template <typename TRecord, size_t InitialBlockSize, size_t MaxBlockSize>
- struct TArenaRecordHolder {
- TIntrusivePtr<TProtoArenaHolder> Arena;
- TRecord& Record;
-
- // Arena depends on block size to be a multiple of 8 for correctness
- // FIXME: uncomment these asserts when code is synchronized between repositories
- // static_assert((InitialBlockSize & 7) == 0, "Misaligned InitialBlockSize");
- // static_assert((MaxBlockSize & 7) == 0, "Misaligned MaxBlockSize");
-
- static const google::protobuf::ArenaOptions GetArenaOptions() {
- google::protobuf::ArenaOptions opts;
- opts.initial_block_size = InitialBlockSize;
- opts.max_block_size = MaxBlockSize;
- return opts;
- }
-
- TArenaRecordHolder()
- : Arena(MakeIntrusive<TProtoArenaHolder>(GetArenaOptions()))
- , Record(*Arena->Allocate<TRecord>())
- {};
-
- TArenaRecordHolder(const TRecord& rec)
- : TArenaRecordHolder()
- {
- Record.CopyFrom(rec);
- }
-
- // not allowed to move from another protobuf, it's a potenial copying
- TArenaRecordHolder(TRecord&& rec) = delete;
-
- TArenaRecordHolder(TIntrusivePtr<TProtoArenaHolder> arena)
- : Arena(std::move(arena))
- , Record(*Arena->Allocate<TRecord>())
- {};
- };
-
- template <typename TEv, typename TRecord, ui32 TEventType>
- class TEventPB : public TEventPBBase<TEv, TRecord, TEventType, TRecordHolder<TRecord> > {
- typedef TEventPBBase<TEv, TRecord, TEventType, TRecordHolder<TRecord> > TPbBase;
- // NOTE: No extra fields allowed: TEventPB must be a "template typedef"
- public:
- using TPbBase::TPbBase;
- };
-
- template <typename TEv, typename TRecord, ui32 TEventType, size_t InitialBlockSize = 512, size_t MaxBlockSize = 16*1024>
- using TEventPBWithArena = TEventPBBase<TEv, TRecord, TEventType, TArenaRecordHolder<TRecord, InitialBlockSize, MaxBlockSize> >;
-
- template <typename TEv, typename TRecord, ui32 TEventType>
- class TEventShortDebugPB: public TEventPB<TEv, TRecord, TEventType> {
- public:
- using TBase = TEventPB<TEv, TRecord, TEventType>;
- TEventShortDebugPB() = default;
- explicit TEventShortDebugPB(const TRecord& rec)
- : TBase(rec)
- {
- }
- explicit TEventShortDebugPB(TRecord&& rec)
- : TBase(std::move(rec))
- {
- }
- TString ToString() const override {
- return TypeName<TEv>() + " { " + TBase::Record.ShortDebugString() + " }";
- }
- };
-
- template <typename TEv, typename TRecord, ui32 TEventType>
- class TEventPreSerializedPB: public TEventPB<TEv, TRecord, TEventType> {
- protected:
- using TBase = TEventPB<TEv, TRecord, TEventType>;
- using TSelf = TEventPreSerializedPB<TEv, TRecord, TEventType>;
- using TBase::Record;
-
- public:
- TString PreSerializedData; // already serialized PB data (using message::SerializeToString)
-
- TEventPreSerializedPB() = default;
-
- explicit TEventPreSerializedPB(const TRecord& rec)
- : TBase(rec)
- {
- }
-
- explicit TEventPreSerializedPB(TRecord&& rec)
- : TBase(std::move(rec))
- {
- }
-
- // when remote event received locally this method will merge preserialized data
- const TRecord& GetRecord() {
- TRecord& base(TBase::Record);
- if (!PreSerializedData.empty()) {
- TRecord copy;
- Y_PROTOBUF_SUPPRESS_NODISCARD copy.ParseFromString(PreSerializedData);
- copy.MergeFrom(base);
- base.Swap(&copy);
- PreSerializedData.clear();
- }
- return TBase::Record;
- }
-
- const TRecord& GetRecord() const {
- return const_cast<TSelf*>(this)->GetRecord();
- }
-
- TRecord* MutableRecord() {
- GetRecord(); // Make sure PreSerializedData is parsed
- return &(TBase::Record);
- }
-
- TString ToString() const override {
- return GetRecord().ShortDebugString();
- }
-
- bool SerializeToArcadiaStream(TChunkSerializer* chunker) const override {
- return TBase::SerializeToArcadiaStreamImpl(chunker, PreSerializedData);
- }
-
- ui32 CalculateSerializedSize() const override {
- return PreSerializedData.size() + TBase::CalculateSerializedSize();
- }
-
- size_t GetCachedByteSize() const {
- return PreSerializedData.size() + TBase::GetCachedByteSize();
- }
-
- ui32 CalculateSerializedSizeCached() const override {
- return GetCachedByteSize();
- }
-
- TEventSerializationInfo CreateSerializationInfo() const override {
- return TBase::CreateSerializationInfoImpl(PreSerializedData.size());
- }
- };
-
- inline TActorId ActorIdFromProto(const NActorsProto::TActorId& actorId) {
- return TActorId(actorId.GetRawX1(), actorId.GetRawX2());
- }
-
- inline void ActorIdToProto(const TActorId& src, NActorsProto::TActorId* dest) {
- Y_DEBUG_ABORT_UNLESS(dest);
- dest->SetRawX1(src.RawX1());
- dest->SetRawX2(src.RawX2());
- }
-}
diff --git a/library/cpp/actors/core/event_pb_payload_ut.cpp b/library/cpp/actors/core/event_pb_payload_ut.cpp
deleted file mode 100644
index c75169db44..0000000000
--- a/library/cpp/actors/core/event_pb_payload_ut.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-#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),
- EvArenaMessage,
- EvArenaMessageBig,
- EvMessageWithPayloadPreSerialized
-};
-
-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) {
-
- 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.CreateSerializationInfo());
- UNIT_ASSERT_VALUES_EQUAL(buffers->GetSize(), msg.CalculateSerializedSize());
- TString ser = buffers->GetString();
-
- TString chunkerRes;
- TCoroutineChunkSerializer chunker;
- chunker.SetSerializingEvent(&msg);
- while (!chunker.IsComplete()) {
- char buffer[4096];
- auto range = chunker.FeedBuf(buffer, sizeof(buffer));
- for (auto [data, size] : range) {
- chunkerRes += TString(data, size);
- }
- }
- UNIT_ASSERT_VALUES_EQUAL(chunkerRes, ser);
-
- THolder<IEventBase> ev2 = THolder(TEventTo::Load(buffers.Get()));
- TEventTo& msg2 = static_cast<TEventTo&>(*ev2);
- 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) {
- for (size_t size1 = 0; size1 < 10000; size1 += step1) {
- for (size_t size2 = 0; size2 < 10000; size2 += step2) {
- TestSerializeDeserialize<TEvent, TEvent>(size1, size2);
- }
- }
- }
-
-#if (!defined(_tsan_enabled_))
- Y_UNIT_TEST(SerializeDeserialize) {
- TestAllSizes<TEvMessageWithPayload>();
- }
-#endif
-
-
- struct TEvArenaMessage : TEventPBWithArena<TEvArenaMessage, TMessageWithPayload, EvArenaMessage> {
- };
-
- Y_UNIT_TEST(SerializeDeserializeArena) {
- TestAllSizes<TEvArenaMessage>(500, 111);
- }
-
-
- struct TEvArenaMessageBig : TEventPBWithArena<TEvArenaMessageBig, TMessageWithPayload, EvArenaMessageBig, 4000, 32000> {
- };
-
- Y_UNIT_TEST(SerializeDeserializeArenaBig) {
- TestAllSizes<TEvArenaMessageBig>(111, 500);
- }
-
-
- // Compatible with TEvArenaMessage but doesn't use arenas
- struct TEvArenaMessageWithoutArena : TEventPB<TEvArenaMessageWithoutArena, TMessageWithPayload, EvArenaMessage> {
- };
-
- Y_UNIT_TEST(Compatibility) {
- TestSerializeDeserialize<TEvArenaMessage, TEvArenaMessageWithoutArena>(200, 14010);
- TestSerializeDeserialize<TEvArenaMessageWithoutArena, TEvArenaMessage>(2000, 4010);
- }
-
- Y_UNIT_TEST(PreSerializedCompatibility) {
- // ensure TEventPreSerializedPB and TEventPB are interchangable with no compatibility issues
- TMessageWithPayload msg;
- msg.SetMeta("hello, world!");
- msg.AddPayloadId(123);
- msg.AddPayloadId(999);
- msg.AddSomeData("abc");
- msg.AddSomeData("xyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
-
- TEvMessageWithPayloadPreSerialized e1;
- Y_PROTOBUF_SUPPRESS_NODISCARD msg.SerializeToString(&e1.PreSerializedData);
-
- auto serializer1 = MakeHolder<TAllocChunkSerializer>();
- e1.SerializeToArcadiaStream(serializer1.Get());
- auto buffers1 = serializer1->Release(e1.CreateSerializationInfo());
- UNIT_ASSERT_VALUES_EQUAL(buffers1->GetSize(), e1.CalculateSerializedSize());
- TString ser1 = buffers1->GetString();
-
- TEvMessageWithPayload e2(msg);
- auto serializer2 = MakeHolder<TAllocChunkSerializer>();
- e2.SerializeToArcadiaStream(serializer2.Get());
- auto buffers2 = serializer2->Release(e2.CreateSerializationInfo());
- UNIT_ASSERT_VALUES_EQUAL(buffers2->GetSize(), e2.CalculateSerializedSize());
- TString ser2 = buffers2->GetString();
- UNIT_ASSERT_VALUES_EQUAL(ser1, ser2);
-
- // deserialize
- auto data = MakeIntrusive<TEventSerializedData>(ser1, TEventSerializationInfo{});
- THolder<TEvMessageWithPayloadPreSerialized> parsedEvent(static_cast<TEvMessageWithPayloadPreSerialized*>(TEvMessageWithPayloadPreSerialized::Load(data.Get())));
- UNIT_ASSERT_VALUES_EQUAL(parsedEvent->PreSerializedData, ""); // this field is empty after deserialization
- auto& record = parsedEvent->GetRecord();
- UNIT_ASSERT_VALUES_EQUAL(record.GetMeta(), msg.GetMeta());
- UNIT_ASSERT_VALUES_EQUAL(record.PayloadIdSize(), msg.PayloadIdSize());
- UNIT_ASSERT_VALUES_EQUAL(record.PayloadIdSize(), 2);
- 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
deleted file mode 100644
index 0dfd173651..0000000000
--- a/library/cpp/actors/core/event_pb_ut.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#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;
- bool
- SerializeToArcadiaStream(NActors::TChunkSerializer* chunker) const override {
- return msg->SerializeToZeroCopyStream(chunker);
- }
- bool IsSerializable() const override {
- return true;
- }
- TString ToStringHeader() const override {
- return TString();
- }
- virtual TString Serialize() const {
- return TString();
- }
- 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;
- 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);
- char buf1[87];
- TString bmChunkedSerialized;
- while (!chunker.IsComplete()) {
- auto range = chunker.FeedBuf(&buf1[0], sizeof(buf1));
- for (auto [data, size] : range) {
- bmChunkedSerialized.append(data, size);
- }
- }
- UNIT_ASSERT_EQUAL(bmSerialized, bmChunkedSerialized);
- }
- }
-}
diff --git a/library/cpp/actors/core/events.h b/library/cpp/actors/core/events.h
deleted file mode 100644
index 911a76d35e..0000000000
--- a/library/cpp/actors/core/events.h
+++ /dev/null
@@ -1,224 +0,0 @@
-#pragma once
-
-#include "event.h"
-#include "event_pb.h"
-
-#include <library/cpp/actors/protos/actors.pb.h>
-#include <util/system/unaligned_mem.h>
-
-namespace NActors {
- struct TEvents {
- enum EEventSpace {
- ES_HELLOWORLD = 0,
- ES_SYSTEM = 1,
- ES_INTERCONNECT = 2,
- ES_INTERCONNECT_MSGBUS = 3,
- ES_DNS = 4,
- ES_SOCKET_POLLER = 5,
- ES_LOGGER = 6,
- ES_MON = 7,
- ES_INTERCONNECT_TCP = 8,
- ES_PROFILER = 9,
- ES_YF = 10,
- ES_HTTP = 11,
- ES_PGWIRE = 12,
-
- ES_USERSPACE = 4096,
-
- ES_PRIVATE = (1 << 15) - 16,
- ES_MAX = (1 << 15),
- };
-
-#define EventSpaceBegin(eventSpace) (eventSpace << 16u)
-#define EventSpaceEnd(eventSpace) ((eventSpace << 16u) + (1u << 16u))
-
- struct THelloWorld {
- enum {
- Start = EventSpaceBegin(ES_HELLOWORLD),
- Ping,
- Pong,
- Blob,
- End
- };
-
- static_assert(End < EventSpaceEnd(ES_HELLOWORLD), "expect End < EventSpaceEnd(ES_HELLOWORLD)");
- };
-
- struct TEvPing: public TEventBase<TEvPing, THelloWorld::Ping> {
- DEFINE_SIMPLE_NONLOCAL_EVENT(TEvPing, "HelloWorld: Ping");
- };
-
- struct TEvPong: public TEventBase<TEvPong, THelloWorld::Pong> {
- DEFINE_SIMPLE_NONLOCAL_EVENT(TEvPong, "HelloWorld: Pong");
- };
-
- struct TEvBlob: public TEventBase<TEvBlob, THelloWorld::Blob> {
- const TString Blob;
-
- TEvBlob(const TString& blob) noexcept
- : Blob(blob)
- {
- }
-
- TString ToStringHeader() const noexcept override {
- return "THelloWorld::Blob";
- }
-
- bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
- return serializer->WriteString(&Blob);
- }
-
- static IEventBase* Load(TEventSerializedData* bufs) noexcept {
- return new TEvBlob(bufs->GetString());
- }
-
- bool IsSerializable() const override {
- return true;
- }
- };
-
- struct TSystem {
- enum {
- Start = EventSpaceBegin(ES_SYSTEM),
- Bootstrap, // generic bootstrap event
- Wakeup, // generic timeout
- Subscribe, // generic subscribe to something
- Unsubscribe, // generic unsubscribe from something
- Delivered, // event delivered
- Undelivered, // event undelivered
- Poison, // request actor to shutdown
- Completed, // generic async job result event
- PoisonTaken, // generic Poison taken (reply to PoisonPill event, i.e. died completely)
- FlushLog,
- CallbackCompletion,
- CallbackException,
- Gone, // Generic notification of actor death
- TrackActor,
- UntrackActor,
- InvokeResult,
- CoroTimeout,
- InvokeQuery,
- Wilson,
- End,
-
- // Compatibility section
- PoisonPill = Poison,
- ActorDied = Gone,
- };
-
- static_assert(End < EventSpaceEnd(ES_SYSTEM), "expect End < EventSpaceEnd(ES_SYSTEM)");
- };
-
- struct TEvBootstrap: public TEventBase<TEvBootstrap, TSystem::Bootstrap> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvBootstrap, "System: TEvBootstrap")
- };
-
- struct TEvPoison : public TEventBase<TEvPoison, TSystem::Poison> {
- DEFINE_SIMPLE_NONLOCAL_EVENT(TEvPoison, "System: TEvPoison")
- };
-
- struct TEvWakeup: public TEventBase<TEvWakeup, TSystem::Wakeup> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvWakeup, "System: TEvWakeup")
-
- TEvWakeup(ui64 tag = 0) : Tag(tag) { }
-
- const ui64 Tag = 0;
- };
-
- struct TEvSubscribe: public TEventBase<TEvSubscribe, TSystem::Subscribe> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvSubscribe, "System: TEvSubscribe")
- };
-
- struct TEvUnsubscribe: public TEventBase<TEvUnsubscribe, TSystem::Unsubscribe> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvUnsubscribe, "System: TEvUnsubscribe")
- };
-
- struct TEvUndelivered: public TEventBase<TEvUndelivered, TSystem::Undelivered> {
- enum EReason {
- ReasonUnknown,
- ReasonActorUnknown,
- Disconnected
- };
- const ui32 SourceType;
- const EReason Reason;
- const bool Unsure;
- const TString Data;
-
- TEvUndelivered(ui32 sourceType, ui32 reason, bool unsure = false)
- : SourceType(sourceType)
- , Reason(static_cast<EReason>(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); }
-
- static void Out(IOutputStream& o, EReason x);
-
- 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;
- }
- };
-
- struct TEvCompleted: public TEventBase<TEvCompleted, TSystem::Completed> {
- const ui32 Id;
- const ui32 Status;
- TEvCompleted(ui32 id = 0, ui32 status = 0)
- : Id(id)
- , Status(status)
- {
- }
-
- DEFINE_SIMPLE_LOCAL_EVENT(TEvCompleted, "System: TEvCompleted")
- };
-
- struct TEvPoisonTaken: public TEventBase<TEvPoisonTaken, TSystem::PoisonTaken> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvPoisonTaken, "System: TEvPoisonTaken")
- };
-
- struct TEvFlushLog: public TEventBase<TEvFlushLog, TSystem::FlushLog> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvFlushLog, "System: TEvFlushLog")
- };
-
- struct TEvCallbackException: public TEventPB<TEvCallbackException,
- NActorsProto::TCallbackException,
- TSystem::CallbackException> {
- TEvCallbackException(const TActorId& id, const TString& msg) {
- ActorIdToProto(id, Record.MutableActorId());
- Record.SetExceptionMessage(msg);
- }
- };
-
- struct TEvCallbackCompletion: public TEventPB<TEvCallbackCompletion,
- NActorsProto::TActorId,
- TSystem::CallbackCompletion> {
- TEvCallbackCompletion(const TActorId& id) {
- ActorIdToProto(id, &Record);
- }
- };
-
- struct TEvGone: public TEventBase<TEvGone, TSystem::Gone> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvGone, "System: TEvGone")
- };
-
- struct TEvInvokeResult;
-
- using TEvPoisonPill = TEvPoison; // Legacy name, deprecated
- using TEvActorDied = TEvGone;
- };
-}
-
-template <>
-inline void Out<NActors::TEvents::TEvUndelivered::EReason>(IOutputStream& o, NActors::TEvents::TEvUndelivered::EReason x) {
- NActors::TEvents::TEvUndelivered::Out(o, x);
-}
diff --git a/library/cpp/actors/core/events_undelivered.cpp b/library/cpp/actors/core/events_undelivered.cpp
deleted file mode 100644
index 7804d5c09d..0000000000
--- a/library/cpp/actors/core/events_undelivered.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "events.h"
-#include "actorsystem.h"
-
-namespace NActors {
- TString TEvents::TEvUndelivered::ToStringHeader() const {
- return "TSystem::Undelivered";
- }
-
- bool TEvents::TEvUndelivered::SerializeToArcadiaStream(TChunkSerializer *serializer) const {
- Y_ABORT_UNLESS(!Unsure); // these are local-only events generated by Interconnect
- return serializer->WriteString(&Data);
- }
-
- void TEvents::TEvUndelivered::Out(IOutputStream& o, EReason x) {
- switch (x) {
- case ReasonActorUnknown:
- o << "ActorUnknown";
- break;
- case Disconnected:
- o << "Disconnected";
- break;
- default:
- o << "Undefined";
- break;
- }
- }
-
- bool TEvents::TEvUndelivered::IsSerializable() const {
- return true;
- }
-
- IEventBase* TEvents::TEvUndelivered::Load(TEventSerializedData* bufs) {
- TString str = bufs->GetString();
- Y_ABORT_UNLESS(str.size() == (sizeof(ui32) + sizeof(ui32)));
- const char* p = str.data();
- const ui64 sourceType = ReadUnaligned<ui32>(p + 0);
- const ui64 reason = ReadUnaligned<ui32>(p + 4);
- return new TEvUndelivered(sourceType, reason);
- }
-
- std::unique_ptr<IEventHandle> IEventHandle::ForwardOnNondelivery(std::unique_ptr<IEventHandle>&& ev, ui32 reason, bool unsure) {
- if (ev->Flags & FlagForwardOnNondelivery) {
- const ui32 updatedFlags = ev->Flags & ~(FlagForwardOnNondelivery | FlagSubscribeOnSession);
- const TActorId recp = ev->OnNondeliveryHolder ? ev->OnNondeliveryHolder->Recipient : TActorId();
-
- if (ev->Event)
- return std::unique_ptr<IEventHandle>(new IEventHandle(recp, ev->Sender, ev->Event.Release(), updatedFlags, ev->Cookie, &ev->Recipient, std::move(ev->TraceId)));
- else
- return std::unique_ptr<IEventHandle>(new IEventHandle(ev->Type, updatedFlags, recp, ev->Sender, ev->Buffer, ev->Cookie, &ev->Recipient, std::move(ev->TraceId)));
- }
-
- if (ev->Flags & FlagTrackDelivery) {
- const ui32 updatedFlags = ev->Flags & ~(FlagTrackDelivery | FlagSubscribeOnSession | FlagGenerateUnsureUndelivered);
- return std::unique_ptr<IEventHandle>(new IEventHandle(ev->Sender, ev->Recipient, new TEvents::TEvUndelivered(ev->Type, reason, unsure), updatedFlags,
- ev->Cookie, nullptr, std::move(ev->TraceId)));
- }
- return {};
- }
-}
diff --git a/library/cpp/actors/core/executelater.h b/library/cpp/actors/core/executelater.h
deleted file mode 100644
index 1d5b5fa5a9..0000000000
--- a/library/cpp/actors/core/executelater.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#pragma once
-
-#include "actor_bootstrapped.h"
-
-#include <utility>
-
-namespace NActors {
- template <typename TCallback>
- class TExecuteLater: public TActorBootstrapped<TExecuteLater<TCallback>> {
- public:
-
- static constexpr char ActorName[] = "AS_EXECUTE_LATER";
-
- TExecuteLater(
- TCallback&& callback,
- IActor::EActivityType activityType,
- ui32 channel = 0,
- ui64 cookie = 0,
- const TActorId& reportCompletionTo = TActorId(),
- const TActorId& reportExceptionTo = TActorId()) noexcept
- : Callback(std::move(callback))
- , Channel(channel)
- , Cookie(cookie)
- , ReportCompletionTo(reportCompletionTo)
- , ReportExceptionTo(reportExceptionTo)
- {
- this->SetActivityType(activityType);
- }
-
- void Bootstrap(const TActorContext& ctx) noexcept {
- try {
- {
- /* RAII, Callback should be destroyed right before sending
- TEvCallbackCompletion */
-
- auto local = std::move(Callback);
- using T = decltype(local);
-
- if constexpr (std::is_invocable_v<T, const TActorContext&>) {
- local(ctx);
- } else {
- local();
- }
- }
-
- if (ReportCompletionTo) {
- ctx.Send(ReportCompletionTo,
- new TEvents::TEvCallbackCompletion(ctx.SelfID),
- Channel, Cookie);
- }
- } catch (...) {
- if (ReportExceptionTo) {
- const TString msg = CurrentExceptionMessage();
- ctx.Send(ReportExceptionTo,
- new TEvents::TEvCallbackException(ctx.SelfID, msg),
- Channel, Cookie);
- }
- }
-
- this->Die(ctx);
- }
-
- private:
- TCallback Callback;
- const ui32 Channel;
- const ui64 Cookie;
- const TActorId ReportCompletionTo;
- const TActorId ReportExceptionTo;
- };
-
- template <typename T>
- IActor* CreateExecuteLaterActor(
- T&& func,
- IActor::EActivityType activityType,
- ui32 channel = 0,
- ui64 cookie = 0,
- const TActorId& reportCompletionTo = TActorId(),
- const TActorId& reportExceptionTo = TActorId()) noexcept {
- return new TExecuteLater<T>(std::forward<T>(func),
- activityType,
- channel,
- cookie,
- reportCompletionTo,
- reportExceptionTo);
- }
-}
diff --git a/library/cpp/actors/core/executor_pool.h b/library/cpp/actors/core/executor_pool.h
deleted file mode 100644
index 5498a6403e..0000000000
--- a/library/cpp/actors/core/executor_pool.h
+++ /dev/null
@@ -1,154 +0,0 @@
-#pragma once
-
-#include "event.h"
-#include "scheduler_queue.h"
-
-namespace NActors {
- class TActorSystem;
- struct TMailboxHeader;
- struct TWorkerContext;
- struct TExecutorPoolStats;
- struct TExecutorThreadStats;
- class ISchedulerCookie;
-
- struct TCpuConsumption {
- double ConsumedUs = 0;
- double BookedUs = 0;
- ui64 NotEnoughCpuExecutions = 0;
-
- void Add(const TCpuConsumption& other) {
- ConsumedUs += other.ConsumedUs;
- BookedUs += other.BookedUs;
- NotEnoughCpuExecutions += other.NotEnoughCpuExecutions;
- }
- };
-
- class IExecutorPool : TNonCopyable {
- public:
- const ui32 PoolId;
-
- TAtomic ActorRegistrations;
- TAtomic DestroyedActors;
-
- IExecutorPool(ui32 poolId)
- : PoolId(poolId)
- , ActorRegistrations(0)
- , DestroyedActors(0)
- {
- }
-
- virtual ~IExecutorPool() {
- }
-
- // for workers
- virtual void Initialize(TWorkerContext& wctx) {
- Y_UNUSED(wctx);
- }
- virtual ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) = 0;
- virtual void ReclaimMailbox(TMailboxType::EType mailboxType, ui32 hint, TWorkerId workerId, ui64 revolvingCounter) = 0;
- virtual TMailboxHeader *ResolveMailbox(ui32 hint) = 0;
-
- /**
- * Schedule one-shot event that will be send at given time point in the future.
- *
- * @param deadline the wallclock time point in future when event must be send
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- * @param workerId index of thread which will perform event dispatching
- */
- virtual void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) = 0;
-
- /**
- * Schedule one-shot event that will be send at given time point in the future.
- *
- * @param deadline the monotonic time point in future when event must be send
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- * @param workerId index of thread which will perform event dispatching
- */
- virtual void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) = 0;
-
- /**
- * Schedule one-shot event that will be send after given delay.
- *
- * @param delta the time from now to delay event sending
- * @param ev the event to send
- * @param cookie cookie that will be piggybacked with event
- * @param workerId index of thread which will perform event dispatching
- */
- virtual void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) = 0;
-
- // for actorsystem
- virtual bool Send(TAutoPtr<IEventHandle>& ev) = 0;
- virtual bool SpecificSend(TAutoPtr<IEventHandle>& ev) = 0;
- virtual void ScheduleActivation(ui32 activation) = 0;
- virtual void SpecificScheduleActivation(ui32 activation) = 0;
- virtual void ScheduleActivationEx(ui32 activation, ui64 revolvingCounter) = 0;
- virtual TActorId Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingCounter, const TActorId& parentId) = 0;
- virtual TActorId Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) = 0;
-
- // lifecycle stuff
- virtual void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) = 0;
- virtual void Start() = 0;
- virtual void PrepareStop() = 0;
- virtual void Shutdown() = 0;
- virtual bool Cleanup() = 0;
-
- virtual void GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const {
- // TODO: make pure virtual and override everywhere
- Y_UNUSED(poolStats);
- Y_UNUSED(statsCopy);
- }
-
- virtual TString GetName() const {
- return TString();
- }
-
- virtual ui32 GetThreads() const {
- return 1;
- }
-
- virtual i16 GetPriority() const {
- return 0;
- }
-
- // generic
- virtual TAffinity* Affinity() const = 0;
-
- virtual void SetRealTimeMode() const {}
-
- virtual i16 GetThreadCount() const {
- return 1;
- }
-
- virtual void SetThreadCount(i16 threads) {
- Y_UNUSED(threads);
- }
-
- virtual void SetSpinThresholdCycles(ui32 cycles) {
- Y_UNUSED(cycles);
- }
-
- virtual i16 GetBlockingThreadCount() const {
- return 0;
- }
-
- virtual i16 GetDefaultThreadCount() const {
- return 1;
- }
-
- virtual i16 GetMinThreadCount() const {
- return 1;
- }
-
- virtual i16 GetMaxThreadCount() const {
- return 1;
- }
-
- virtual TCpuConsumption GetThreadCpuConsumption(i16 threadIdx) {
- Y_UNUSED(threadIdx);
- return TCpuConsumption{0.0, 0.0};
- }
- };
-
-}
diff --git a/library/cpp/actors/core/executor_pool_base.cpp b/library/cpp/actors/core/executor_pool_base.cpp
deleted file mode 100644
index 1c9a536b9b..0000000000
--- a/library/cpp/actors/core/executor_pool_base.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-#include "actorsystem.h"
-#include "actor.h"
-#include "executor_pool_base.h"
-#include "executor_pool_basic_feature_flags.h"
-#include "executor_thread.h"
-#include "mailbox.h"
-#include "probes.h"
-#include <library/cpp/actors/util/datetime.h>
-
-namespace NActors {
- LWTRACE_USING(ACTORLIB_PROVIDER);
-
- void DoActorInit(TActorSystem* sys, IActor* actor, const TActorId& self, const TActorId& owner) {
- actor->SelfActorId = self;
- actor->DoActorInit();
- actor->Registered(sys, owner);
- }
-
- TExecutorPoolBaseMailboxed::TExecutorPoolBaseMailboxed(ui32 poolId)
- : IExecutorPool(poolId)
- , ActorSystem(nullptr)
- , MailboxTable(new TMailboxTable)
- {}
-
- TExecutorPoolBaseMailboxed::~TExecutorPoolBaseMailboxed() {
- MailboxTable.Destroy();
- }
-
-#if defined(ACTORSLIB_COLLECT_EXEC_STATS)
- void TExecutorPoolBaseMailboxed::RecalculateStuckActors(TExecutorThreadStats& stats) const {
- if (!ActorSystem || !ActorSystem->MonitorStuckActors()) {
- return;
- }
-
- const TMonotonic now = ActorSystem->Monotonic();
-
- for (auto& u : stats.UsageByActivity) {
- u.fill(0);
- }
-
- auto accountUsage = [&](ui32 activityType, double usage) {
- Y_ABORT_UNLESS(0 <= usage);
- Y_ABORT_UNLESS(usage <= 1);
- int bin = Min<int>(9, usage * 10);
- ++stats.UsageByActivity[activityType][bin];
- };
-
- std::fill(stats.StuckActorsByActivity.begin(), stats.StuckActorsByActivity.end(), 0);
-
- with_lock (StuckObserverMutex) {
- for (size_t i = 0; i < Actors.size(); ++i) {
- IActor *actor = Actors[i];
- Y_ABORT_UNLESS(actor->StuckIndex == i);
- const TDuration delta = now - actor->LastReceiveTimestamp;
- if (delta > TDuration::Seconds(30)) {
- ++stats.StuckActorsByActivity[actor->GetActivityType()];
- }
- accountUsage(actor->GetActivityType(), actor->GetUsage(GetCycleCountFast()));
- }
- for (const auto& [activityType, usage] : DeadActorsUsage) {
- accountUsage(activityType, usage);
- }
- DeadActorsUsage.clear();
- }
- }
-#endif
-
- TExecutorPoolBase::TExecutorPoolBase(ui32 poolId, ui32 threads, TAffinity* affinity)
- : TExecutorPoolBaseMailboxed(poolId)
- , PoolThreads(threads)
- , ThreadsAffinity(affinity)
- {}
-
- TExecutorPoolBase::~TExecutorPoolBase() {
- while (Activations.Pop(0))
- ;
- }
-
- void TExecutorPoolBaseMailboxed::ReclaimMailbox(TMailboxType::EType mailboxType, ui32 hint, TWorkerId workerId, ui64 revolvingWriteCounter) {
- Y_UNUSED(workerId);
- MailboxTable->ReclaimMailbox(mailboxType, hint, revolvingWriteCounter);
- }
-
- TMailboxHeader *TExecutorPoolBaseMailboxed::ResolveMailbox(ui32 hint) {
- return MailboxTable->Get(hint);
- }
-
- ui64 TExecutorPoolBaseMailboxed::AllocateID() {
- return ActorSystem->AllocateIDSpace(1);
- }
-
- bool TExecutorPoolBaseMailboxed::Send(TAutoPtr<IEventHandle>& ev) {
- Y_DEBUG_ABORT_UNLESS(ev->GetRecipientRewrite().PoolID() == PoolId);
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- RelaxedStore(&ev->SendTime, (::NHPTimer::STime)GetCycleCountFast());
-#endif
- if (TlsThreadContext) {
- TlsThreadContext->IsCurrentRecipientAService = ev->Recipient.IsService();
- }
- return MailboxTable->SendTo(ev, this);
- }
-
- bool TExecutorPoolBaseMailboxed::SpecificSend(TAutoPtr<IEventHandle>& ev) {
- Y_DEBUG_ABORT_UNLESS(ev->GetRecipientRewrite().PoolID() == PoolId);
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- RelaxedStore(&ev->SendTime, (::NHPTimer::STime)GetCycleCountFast());
-#endif
- if (TlsThreadContext) {
- TlsThreadContext->IsCurrentRecipientAService = ev->Recipient.IsService();
- }
- return MailboxTable->SpecificSendTo(ev, this);
- }
-
- void TExecutorPoolBase::ScheduleActivation(ui32 activation) {
- ScheduleActivationEx(activation, AtomicIncrement(ActivationsRevolvingCounter));
- }
-
- Y_FORCE_INLINE bool IsAllowedToCapture(IExecutorPool *self) {
- if (TlsThreadContext->Pool != self || TlsThreadContext->CapturedType == ESendingType::Tail) {
- return false;
- }
- return TlsThreadContext->SendingType != ESendingType::Common;
- }
-
- Y_FORCE_INLINE bool IsTailSend(IExecutorPool *self) {
- return TlsThreadContext->Pool == self && TlsThreadContext->SendingType == ESendingType::Tail && TlsThreadContext->CapturedType != ESendingType::Tail;
- }
-
- void TExecutorPoolBase::SpecificScheduleActivation(ui32 activation) {
- if (NFeatures::IsCommon() && IsAllowedToCapture(this) || IsTailSend(this)) {
- std::swap(TlsThreadContext->CapturedActivation, activation);
- TlsThreadContext->CapturedType = TlsThreadContext->SendingType;
- }
- if (activation) {
- ScheduleActivationEx(activation, AtomicIncrement(ActivationsRevolvingCounter));
- }
- }
-
- TActorId TExecutorPoolBaseMailboxed::Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingWriteCounter, const TActorId& parentId) {
- NHPTimer::STime hpstart = GetCycleCountFast();
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- ui32 at = actor->GetActivityType();
- Y_DEBUG_ABORT_UNLESS(at < Stats.ActorsAliveByActivity.size());
- if (at >= Stats.MaxActivityType()) {
- at = TActorTypeOperator::GetActorActivityIncorrectIndex();
- Y_ABORT_UNLESS(at < Stats.ActorsAliveByActivity.size());
- }
- AtomicIncrement(Stats.ActorsAliveByActivity[at]);
-#endif
- AtomicIncrement(ActorRegistrations);
-
- // first step - find good enough mailbox
- ui32 hint = 0;
- TMailboxHeader* mailbox = nullptr;
-
- if (revolvingWriteCounter == 0)
- revolvingWriteCounter = AtomicIncrement(RegisterRevolvingCounter);
-
- {
- ui32 hintBackoff = 0;
-
- while (hint == 0) {
- hint = MailboxTable->AllocateMailbox(mailboxType, ++revolvingWriteCounter);
- mailbox = MailboxTable->Get(hint);
-
- if (!mailbox->LockFromFree()) {
- MailboxTable->ReclaimMailbox(mailboxType, hintBackoff, ++revolvingWriteCounter);
- hintBackoff = hint;
- hint = 0;
- }
- }
-
- MailboxTable->ReclaimMailbox(mailboxType, hintBackoff, ++revolvingWriteCounter);
- }
-
- const ui64 localActorId = AllocateID();
-
- // ok, got mailbox
- mailbox->AttachActor(localActorId, actor);
-
- // do init
- const TActorId actorId(ActorSystem->NodeId, PoolId, localActorId, hint);
- DoActorInit(ActorSystem, actor, actorId, parentId);
-
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- if (ActorSystem->MonitorStuckActors()) {
- with_lock (StuckObserverMutex) {
- Y_ABORT_UNLESS(actor->StuckIndex == Max<size_t>());
- actor->StuckIndex = Actors.size();
- Actors.push_back(actor);
- }
- }
-#endif
-
- // Once we unlock the mailbox the actor starts running and we cannot use the pointer any more
- actor = nullptr;
-
- switch (mailboxType) {
- case TMailboxType::Simple:
- UnlockFromExecution((TMailboxTable::TSimpleMailbox*)mailbox, this, false, hint, MaxWorkers, ++revolvingWriteCounter);
- break;
- case TMailboxType::Revolving:
- UnlockFromExecution((TMailboxTable::TRevolvingMailbox*)mailbox, this, false, hint, MaxWorkers, ++revolvingWriteCounter);
- break;
- case TMailboxType::HTSwap:
- UnlockFromExecution((TMailboxTable::THTSwapMailbox*)mailbox, this, false, hint, MaxWorkers, ++revolvingWriteCounter);
- break;
- case TMailboxType::ReadAsFilled:
- UnlockFromExecution((TMailboxTable::TReadAsFilledMailbox*)mailbox, this, false, hint, MaxWorkers, ++revolvingWriteCounter);
- break;
- case TMailboxType::TinyReadAsFilled:
- UnlockFromExecution((TMailboxTable::TTinyReadAsFilledMailbox*)mailbox, this, false, hint, MaxWorkers, ++revolvingWriteCounter);
- break;
- default:
- Y_ABORT();
- }
-
- NHPTimer::STime elapsed = GetCycleCountFast() - hpstart;
- if (elapsed > 1000000) {
- LWPROBE(SlowRegisterNew, PoolId, NHPTimer::GetSeconds(elapsed) * 1000.0);
- }
-
- return actorId;
- }
-
- TActorId TExecutorPoolBaseMailboxed::Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) {
- NHPTimer::STime hpstart = GetCycleCountFast();
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- ui32 at = actor->GetActivityType();
- if (at >= Stats.MaxActivityType())
- at = 0;
- AtomicIncrement(Stats.ActorsAliveByActivity[at]);
-#endif
- AtomicIncrement(ActorRegistrations);
-
- const ui64 localActorId = AllocateID();
- mailbox->AttachActor(localActorId, actor);
-
- const TActorId actorId(ActorSystem->NodeId, PoolId, localActorId, hint);
- DoActorInit(ActorSystem, actor, actorId, parentId);
-
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- if (ActorSystem->MonitorStuckActors()) {
- with_lock (StuckObserverMutex) {
- Y_ABORT_UNLESS(actor->StuckIndex == Max<size_t>());
- actor->StuckIndex = Actors.size();
- Actors.push_back(actor);
- }
- }
-#endif
-
- NHPTimer::STime elapsed = GetCycleCountFast() - hpstart;
- if (elapsed > 1000000) {
- LWPROBE(SlowRegisterAdd, PoolId, NHPTimer::GetSeconds(elapsed) * 1000.0);
- }
-
- return actorId;
- }
-
- TAffinity* TExecutorPoolBase::Affinity() const {
- return ThreadsAffinity.Get();
- }
-
- bool TExecutorPoolBaseMailboxed::Cleanup() {
- return MailboxTable->Cleanup();
- }
-
- ui32 TExecutorPoolBase::GetThreads() const {
- return PoolThreads;
- }
-}
diff --git a/library/cpp/actors/core/executor_pool_base.h b/library/cpp/actors/core/executor_pool_base.h
deleted file mode 100644
index 6bfabb527f..0000000000
--- a/library/cpp/actors/core/executor_pool_base.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#pragma once
-
-#include "executor_pool.h"
-#include "executor_thread.h"
-#include "mon_stats.h"
-#include "scheduler_queue.h"
-#include <library/cpp/actors/util/affinity.h>
-#include <library/cpp/actors/util/unordered_cache.h>
-#include <library/cpp/actors/util/threadparkpad.h>
-
-namespace NActors {
- class TActorSystem;
-
- class TExecutorPoolBaseMailboxed: public IExecutorPool {
- protected:
- TActorSystem* ActorSystem;
- THolder<TMailboxTable> MailboxTable;
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- // Need to have per pool object to collect stats like actor registrations (because
- // registrations might be done in threads from other pools)
- TExecutorThreadStats Stats;
-
- // Stuck actor monitoring
- TMutex StuckObserverMutex;
- std::vector<IActor*> Actors;
- mutable std::vector<std::tuple<ui32, double>> DeadActorsUsage;
- friend class TExecutorThread;
- void RecalculateStuckActors(TExecutorThreadStats& stats) const;
-#endif
- TAtomic RegisterRevolvingCounter = 0;
- ui64 AllocateID();
- public:
- explicit TExecutorPoolBaseMailboxed(ui32 poolId);
- ~TExecutorPoolBaseMailboxed();
- void ReclaimMailbox(TMailboxType::EType mailboxType, ui32 hint, TWorkerId workerId, ui64 revolvingWriteCounter) override;
- TMailboxHeader *ResolveMailbox(ui32 hint) override;
- bool Send(TAutoPtr<IEventHandle>& ev) override;
- bool SpecificSend(TAutoPtr<IEventHandle>& ev) override;
- TActorId Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingWriteCounter, const TActorId& parentId) override;
- TActorId Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) override;
- bool Cleanup() override;
- };
-
- class TExecutorPoolBase: public TExecutorPoolBaseMailboxed {
- protected:
- const i16 PoolThreads;
- TIntrusivePtr<TAffinity> ThreadsAffinity;
- TAtomic Semaphore = 0;
- TUnorderedCache<ui32, 512, 4> Activations;
- TAtomic ActivationsRevolvingCounter = 0;
- volatile bool StopFlag = false;
- public:
- TExecutorPoolBase(ui32 poolId, ui32 threads, TAffinity* affinity);
- ~TExecutorPoolBase();
- void ScheduleActivation(ui32 activation) override;
- void SpecificScheduleActivation(ui32 activation) override;
- TAffinity* Affinity() const override;
- ui32 GetThreads() const override;
- };
-
- void DoActorInit(TActorSystem*, IActor*, const TActorId&, const TActorId&);
-}
diff --git a/library/cpp/actors/core/executor_pool_basic.cpp b/library/cpp/actors/core/executor_pool_basic.cpp
deleted file mode 100644
index 4a9019e26d..0000000000
--- a/library/cpp/actors/core/executor_pool_basic.cpp
+++ /dev/null
@@ -1,749 +0,0 @@
-#include "executor_pool_basic.h"
-#include "executor_pool_basic_feature_flags.h"
-#include "actor.h"
-#include "probes.h"
-#include "mailbox.h"
-#include <library/cpp/actors/util/affinity.h>
-#include <library/cpp/actors/util/datetime.h>
-
-#ifdef _linux_
-#include <pthread.h>
-#endif
-
-namespace NActors {
- LWTRACE_USING(ACTORLIB_PROVIDER);
-
-
- const double TWaitingStatsConstants::HistogramResolutionUs = MaxSpinThersholdUs / BucketCount;
- const ui64 TWaitingStatsConstants::HistogramResolution = NHPTimer::GetCyclesPerSecond() * 0.000001 * HistogramResolutionUs;
-
- constexpr TDuration TBasicExecutorPool::DEFAULT_TIME_PER_MAILBOX;
-
- TBasicExecutorPool::TBasicExecutorPool(
- ui32 poolId,
- ui32 threads,
- ui64 spinThreshold,
- const TString& poolName,
- IHarmonizer *harmonizer,
- TAffinity* affinity,
- TDuration timePerMailbox,
- ui32 eventsPerMailbox,
- int realtimePriority,
- ui32 maxActivityType,
- i16 minThreadCount,
- i16 maxThreadCount,
- i16 defaultThreadCount,
- i16 priority)
- : TExecutorPoolBase(poolId, threads, affinity)
- , DefaultSpinThresholdCycles(spinThreshold * NHPTimer::GetCyclesPerSecond() * 0.000001) // convert microseconds to cycles
- , SpinThresholdCycles(DefaultSpinThresholdCycles)
- , SpinThresholdCyclesPerThread(new NThreading::TPadded<std::atomic<ui64>>[threads])
- , Threads(new NThreading::TPadded<TThreadCtx>[threads])
- , WaitingStats(new TWaitingStats<ui64>[threads])
- , PoolName(poolName)
- , TimePerMailbox(timePerMailbox)
- , EventsPerMailbox(eventsPerMailbox)
- , RealtimePriority(realtimePriority)
- , ThreadUtilization(0)
- , MaxUtilizationCounter(0)
- , MaxUtilizationAccumulator(0)
- , WrongWakenedThreadCount(0)
- , ThreadCount(threads)
- , MinThreadCount(minThreadCount)
- , MaxThreadCount(maxThreadCount)
- , DefaultThreadCount(defaultThreadCount)
- , Harmonizer(harmonizer)
- , Priority(priority)
- {
- if constexpr (NFeatures::IsLocalQueues()) {
- LocalQueues.Reset(new NThreading::TPadded<std::queue<ui32>>[threads]);
- if constexpr (NFeatures::TLocalQueuesFeatureFlags::FIXED_LOCAL_QUEUE_SIZE) {
- LocalQueueSize = *NFeatures::TLocalQueuesFeatureFlags::FIXED_LOCAL_QUEUE_SIZE;
- } else {
- LocalQueueSize = NFeatures::TLocalQueuesFeatureFlags::MIN_LOCAL_QUEUE_SIZE;
- }
- }
- if constexpr (NFeatures::TSpinFeatureFlags::CalcPerThread) {
- for (ui32 idx = 0; idx < threads; ++idx) {
- SpinThresholdCyclesPerThread[idx].store(0);
- }
- }
- if constexpr (NFeatures::TSpinFeatureFlags::UsePseudoMovingWindow) {
- MovingWaitingStats.Reset(new TWaitingStats<double>[threads]);
- }
-
- Y_UNUSED(maxActivityType);
- i16 limit = Min(threads, (ui32)Max<i16>());
- if (DefaultThreadCount) {
- DefaultThreadCount = Min(DefaultThreadCount, limit);
- } else {
- DefaultThreadCount = limit;
- }
-
- MaxThreadCount = Min(Max(MaxThreadCount, DefaultThreadCount), limit);
-
- if (MinThreadCount) {
- MinThreadCount = Max((i16)1, Min(MinThreadCount, DefaultThreadCount));
- } else {
- MinThreadCount = DefaultThreadCount;
- }
- ThreadCount = MaxThreadCount;
- auto semaphore = TSemaphore();
- semaphore.CurrentThreadCount = ThreadCount;
- Semaphore = semaphore.ConverToI64();
- }
-
- TBasicExecutorPool::TBasicExecutorPool(const TBasicExecutorPoolConfig& cfg, IHarmonizer *harmonizer)
- : TBasicExecutorPool(
- cfg.PoolId,
- cfg.Threads,
- cfg.SpinThreshold,
- cfg.PoolName,
- harmonizer,
- new TAffinity(cfg.Affinity),
- cfg.TimePerMailbox,
- cfg.EventsPerMailbox,
- cfg.RealtimePriority,
- 0,
- cfg.MinThreadCount,
- cfg.MaxThreadCount,
- cfg.DefaultThreadCount,
- cfg.Priority
- )
- {
- SetSharedExecutorsCount(cfg.SharedExecutorsCount);
- SoftProcessingDurationTs = cfg.SoftProcessingDurationTs;
- ActorSystemProfile = cfg.ActorSystemProfile;
- }
-
- TBasicExecutorPool::~TBasicExecutorPool() {
- Threads.Destroy();
- }
-
- bool TBasicExecutorPool::GoToSleep(TThreadCtx& threadCtx, TTimers &timers) {
- do {
- timers.HPNow = GetCycleCountFast();
- timers.Elapsed += timers.HPNow - timers.HPStart;
- if (threadCtx.WaitingPad.Park()) // interrupted
- return true;
- timers.HPStart = GetCycleCountFast();
- timers.Parked += timers.HPStart - timers.HPNow;
- } while (AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_BLOCKED && !RelaxedLoad(&StopFlag));
- return false;
- }
-
- ui32 TBasicExecutorPool::GoToSpin(TThreadCtx& threadCtx, i64 start, i64 &end) {
- ui32 spinPauseCount = 0;
- i64 spinThresholdCycles = 0;
- if constexpr (NFeatures::TSpinFeatureFlags::CalcPerThread) {
- spinThresholdCycles = SpinThresholdCyclesPerThread[TlsThreadContext->WorkerId].load();
- } else {
- spinThresholdCycles = SpinThresholdCycles.load();
- }
- do {
- end = GetCycleCountFast();
- if (end >= (start + spinThresholdCycles) || AtomicLoad(&threadCtx.WaitingFlag) != TThreadCtx::WS_ACTIVE) {
- return spinPauseCount;
- }
-
- SpinLockPause();
- spinPauseCount++;
- } while (!RelaxedLoad(&StopFlag));
-
- return spinPauseCount;
- }
-
- bool TBasicExecutorPool::GoToWaiting(TThreadCtx& threadCtx, TTimers &timers, bool needToBlock) {
-#if defined ACTORSLIB_COLLECT_EXEC_STATS
- if (AtomicGetAndIncrement(ThreadUtilization) == 0) {
- // Initially counter contains -t0, the pool start timestamp
- // When the first thread goes to sleep we add t1, so the counter
- // becomes t1-t0 >= 0, or the duration of max utilization so far.
- // If the counter was negative and becomes positive, that means
- // counter just turned into a duration and we should store that
- // duration. Otherwise another thread raced with us and
- // subtracted some other timestamp t2.
- const i64 t = GetCycleCountFast();
- const i64 x = AtomicGetAndAdd(MaxUtilizationCounter, t);
- if (x < 0 && x + t > 0)
- AtomicStore(&MaxUtilizationAccumulator, x + t);
- }
-#endif
-
- i64 startWaiting = GetCycleCountFast();
- i64 endSpinning = 0;
- TAtomic state = AtomicLoad(&threadCtx.WaitingFlag);
- bool wasSleeping = false;
- Y_ABORT_UNLESS(state == TThreadCtx::WS_NONE, "WaitingFlag# %d", int(state));
-
- if (SpinThresholdCycles > 0 && !needToBlock) {
- // spin configured period
- AtomicSet(threadCtx.WaitingFlag, TThreadCtx::WS_ACTIVE);
- ui32 spinPauseCount = GoToSpin(threadCtx, startWaiting, endSpinning);
- SpinningTimeUs += endSpinning - startWaiting;
- // then - sleep
- if (AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_ACTIVE) {
- if (AtomicCas(&threadCtx.WaitingFlag, TThreadCtx::WS_BLOCKED, TThreadCtx::WS_ACTIVE)) {
- if (NFeatures::TCommonFeatureFlags::ProbeSpinCycles) {
- LWPROBE(SpinCycles, PoolId, PoolName, spinPauseCount, true);
- }
-
- wasSleeping = true;
- if (GoToSleep(threadCtx, timers)) { // interrupted
- return true;
- }
- AllThreadsSleep.store(false);
- }
- }
- if (NFeatures::TCommonFeatureFlags::ProbeSpinCycles && !wasSleeping) {
- LWPROBE(SpinCycles, PoolId, PoolName, spinPauseCount, false);
- }
- } else {
- AtomicSet(threadCtx.WaitingFlag, TThreadCtx::WS_BLOCKED);
- wasSleeping = true;
- if (GoToSleep(threadCtx, timers)) { // interrupted
- return true;
- }
- AllThreadsSleep.store(false);
- }
-
- i64 needTimeTs = threadCtx.StartWakingTs.exchange(0);
- if (wasSleeping && needTimeTs) {
- ui64 waitingDuration = std::max<i64>(0, needTimeTs - startWaiting);
- ui64 awakingDuration = std::max<i64>(0, GetCycleCountFast() - needTimeTs);
- WaitingStats[TlsThreadContext->WorkerId].AddAwakening(waitingDuration, awakingDuration);
- } else {
- ui64 waitingDuration = std::max<i64>(0, endSpinning - startWaiting);
- if (wasSleeping) {
- WaitingStats[TlsThreadContext->WorkerId].AddFastAwakening(waitingDuration);
- } else {
- WaitingStats[TlsThreadContext->WorkerId].Add(waitingDuration);
- }
- }
-
- Y_DEBUG_ABORT_UNLESS(AtomicLoad(&StopFlag) || AtomicLoad(&threadCtx.WaitingFlag) == TThreadCtx::WS_NONE);
-
-#if defined ACTORSLIB_COLLECT_EXEC_STATS
- if (AtomicDecrement(ThreadUtilization) == 0) {
- // When we started sleeping counter contained t1-t0, or the
- // last duration of max utilization. Now we subtract t2 >= t1,
- // which turns counter negative again, and the next sleep cycle
- // at timestamp t3 would be adding some new duration t3-t2.
- // If the counter was positive and becomes negative that means
- // there are no current races with other threads and we should
- // store the last positive duration we observed. Multiple
- // threads may be adding and subtracting values in potentially
- // arbitrary order, which would cause counter to oscillate
- // around zero. When it crosses zero is a good indication of a
- // correct value.
- const i64 t = GetCycleCountFast();
- const i64 x = AtomicGetAndAdd(MaxUtilizationCounter, -t);
- if (x > 0 && x - t < 0)
- AtomicStore(&MaxUtilizationAccumulator, x);
- }
-#endif
- return false;
- }
-
- void TBasicExecutorPool::AskToGoToSleep(bool *needToWait, bool *needToBlock) {
- TAtomic x = AtomicGet(Semaphore);
- do {
- i64 oldX = x;
- TSemaphore semaphore = TSemaphore::GetSemaphore(x);;
- if (semaphore.CurrentSleepThreadCount < 0) {
- semaphore.CurrentSleepThreadCount++;
- x = AtomicGetAndCas(&Semaphore, semaphore.ConverToI64(), x);
- if (x == oldX) {
- *needToWait = true;
- *needToBlock = true;
- return;
- }
- continue;
- }
-
- if (semaphore.OldSemaphore == 0) {
- semaphore.CurrentSleepThreadCount++;
- if (semaphore.CurrentSleepThreadCount == AtomicLoad(&ThreadCount)) {
- AllThreadsSleep.store(true);
- }
- x = AtomicGetAndCas(&Semaphore, semaphore.ConverToI64(), x);
- if (x == oldX) {
- *needToWait = true;
- *needToBlock = false;
- return;
- }
- continue;
- }
-
- *needToWait = false;
- *needToBlock = false;
- return;
- } while (true);
- }
-
- ui32 TBasicExecutorPool::GetReadyActivationCommon(TWorkerContext& wctx, ui64 revolvingCounter) {
- TWorkerId workerId = wctx.WorkerId;
- Y_DEBUG_ABORT_UNLESS(workerId < PoolThreads);
-
- TTimers timers;
-
- if (Harmonizer) {
- LWPROBE(TryToHarmonize, PoolId, PoolName);
- Harmonizer->Harmonize(timers.HPStart);
- }
-
- if (workerId >= 0) {
- AtomicSet(Threads[workerId].WaitingFlag, TThreadCtx::WS_NONE);
- }
-
- TAtomic x = AtomicGet(Semaphore);
- TSemaphore semaphore = TSemaphore::GetSemaphore(x);
- while (!RelaxedLoad(&StopFlag)) {
- if (!semaphore.OldSemaphore || semaphore.CurrentSleepThreadCount < 0) {
- if (workerId < 0 || !wctx.IsNeededToWaitNextActivation) {
- timers.HPNow = GetCycleCountFast();
- wctx.AddElapsedCycles(ActorSystemIndex, timers.HPNow - timers.HPStart);
- return 0;
- }
-
- bool needToWait = false;
- bool needToBlock = false;
- AskToGoToSleep(&needToWait, &needToBlock);
- if (needToWait) {
- if (GoToWaiting(Threads[workerId], timers, needToBlock)) { // interrupted
- return 0;
- }
- }
- } else {
- if (const ui32 activation = Activations.Pop(++revolvingCounter)) {
- if (workerId >= 0) {
- AtomicSet(Threads[workerId].WaitingFlag, TThreadCtx::WS_RUNNING);
- }
- AtomicDecrement(Semaphore);
- timers.HPNow = GetCycleCountFast();
- timers.Elapsed += timers.HPNow - timers.HPStart;
- wctx.AddElapsedCycles(ActorSystemIndex, timers.Elapsed);
- if (timers.Parked > 0) {
- wctx.AddParkedCycles(timers.Parked);
- }
-
- return activation;
- }
- semaphore.CurrentSleepThreadCount++;
- }
-
- SpinLockPause();
- x = AtomicGet(Semaphore);
- semaphore = TSemaphore::GetSemaphore(x);
- }
-
- return 0;
- }
-
- ui32 TBasicExecutorPool::GetReadyActivationLocalQueue(TWorkerContext& wctx, ui64 revolvingCounter) {
- TWorkerId workerId = wctx.WorkerId;
- Y_DEBUG_ABORT_UNLESS(workerId < static_cast<i32>(PoolThreads));
-
- if (workerId >= 0 && LocalQueues[workerId].size()) {
- ui32 activation = LocalQueues[workerId].front();
- LocalQueues[workerId].pop();
- return activation;
- } else {
- TlsThreadContext->WriteTurn = 0;
- TlsThreadContext->LocalQueueSize = LocalQueueSize.load(std::memory_order_relaxed);
- }
- return GetReadyActivationCommon(wctx, revolvingCounter);
- }
-
- ui32 TBasicExecutorPool::GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) {
- if constexpr (NFeatures::IsLocalQueues()) {
- if (SharedExecutorsCount) {
- return GetReadyActivationCommon(wctx, revolvingCounter);
- }
- return GetReadyActivationLocalQueue(wctx, revolvingCounter);
- } else {
- return GetReadyActivationCommon(wctx, revolvingCounter);
- }
- return 0;
- }
-
- inline void TBasicExecutorPool::WakeUpLoop(i16 currentThreadCount) {
- if (AllThreadsSleep) {
- TThreadCtx& hotThreadCtx = Threads[0];
- if (AtomicCas(&hotThreadCtx.WaitingFlag, TThreadCtx::WS_NONE, TThreadCtx::WS_ACTIVE)) {
- return;
- }
-
- TThreadCtx& coldThreadCtx = Threads[AtomicLoad(&ThreadCount) - 1];
- if (AtomicCas(&coldThreadCtx.WaitingFlag, TThreadCtx::WS_NONE, TThreadCtx::WS_BLOCKED)) {
- if (TlsThreadContext && TlsThreadContext->WaitingStats) {
- ui64 beforeUnpark = GetCycleCountFast();
- coldThreadCtx.StartWakingTs = beforeUnpark;
- coldThreadCtx.WaitingPad.Unpark();
- TlsThreadContext->WaitingStats->AddWakingUp(GetCycleCountFast() - beforeUnpark);
- } else {
- coldThreadCtx.WaitingPad.Unpark();
- }
- return;
- }
- }
- for (i16 i = 0;;) {
- TThreadCtx& threadCtx = Threads[i];
- TThreadCtx::EWaitState state = static_cast<TThreadCtx::EWaitState>(AtomicLoad(&threadCtx.WaitingFlag));
- switch (state) {
- case TThreadCtx::WS_NONE:
- case TThreadCtx::WS_RUNNING:
- if (++i >= MaxThreadCount - SharedExecutorsCount) {
- i = 0;
- }
- break;
- case TThreadCtx::WS_ACTIVE:
- case TThreadCtx::WS_BLOCKED:
- if (AtomicCas(&threadCtx.WaitingFlag, TThreadCtx::WS_NONE, state)) {
- if (state == TThreadCtx::WS_BLOCKED) {
- ui64 beforeUnpark = GetCycleCountFast();
- threadCtx.StartWakingTs = beforeUnpark;
- if (TlsThreadContext && TlsThreadContext->WaitingStats) {
- threadCtx.WaitingPad.Unpark();
- TlsThreadContext->WaitingStats->AddWakingUp(GetCycleCountFast() - beforeUnpark);
- } else {
- threadCtx.WaitingPad.Unpark();
- }
- }
- if (i >= currentThreadCount) {
- AtomicIncrement(WrongWakenedThreadCount);
- }
- return;
- }
- break;
- default:
- Y_ABORT();
- }
- }
- }
-
- void TBasicExecutorPool::ScheduleActivationExCommon(ui32 activation, ui64 revolvingCounter, TAtomic x) {
- TSemaphore semaphore = TSemaphore::GetSemaphore(x);
-
- Activations.Push(activation, revolvingCounter);
- bool needToWakeUp = false;
-
- do {
- needToWakeUp = semaphore.CurrentSleepThreadCount > SharedExecutorsCount;
- i64 oldX = semaphore.ConverToI64();
- semaphore.OldSemaphore++;
- if (needToWakeUp) {
- semaphore.CurrentSleepThreadCount--;
- }
- x = AtomicGetAndCas(&Semaphore, semaphore.ConverToI64(), oldX);
- if (x == oldX) {
- break;
- }
- semaphore = TSemaphore::GetSemaphore(x);
- } while (true);
-
- if (needToWakeUp) { // we must find someone to wake-up
- WakeUpLoop(semaphore.CurrentThreadCount);
- }
- }
-
- void TBasicExecutorPool::ScheduleActivationExLocalQueue(ui32 activation, ui64 revolvingWriteCounter) {
- if (TlsThreadContext && TlsThreadContext->Pool == this && TlsThreadContext->WorkerId >= 0) {
- if (++TlsThreadContext->WriteTurn < TlsThreadContext->LocalQueueSize) {
- LocalQueues[TlsThreadContext->WorkerId].push(activation);
- return;
- }
- if (ActorSystemProfile != EASProfile::Default) {
- TAtomic x = AtomicGet(Semaphore);
- TSemaphore semaphore = TSemaphore::GetSemaphore(x);
- if constexpr (NFeatures::TLocalQueuesFeatureFlags::UseIfAllOtherThreadsAreSleeping) {
- if (semaphore.CurrentSleepThreadCount == semaphore.CurrentThreadCount - 1 && semaphore.OldSemaphore == 0) {
- if (LocalQueues[TlsThreadContext->WorkerId].empty()) {
- LocalQueues[TlsThreadContext->WorkerId].push(activation);
- return;
- }
- }
- }
-
- if constexpr (NFeatures::TLocalQueuesFeatureFlags::UseOnMicroburst) {
- if (semaphore.OldSemaphore >= semaphore.CurrentThreadCount) {
- if (LocalQueues[TlsThreadContext->WorkerId].empty() && TlsThreadContext->WriteTurn < 1) {
- TlsThreadContext->WriteTurn++;
- LocalQueues[TlsThreadContext->WorkerId].push(activation);
- return;
- }
- }
- }
- ScheduleActivationExCommon(activation, revolvingWriteCounter, x);
- return;
- }
- }
- ScheduleActivationExCommon(activation, revolvingWriteCounter, AtomicGet(Semaphore));
- }
-
- void TBasicExecutorPool::ScheduleActivationEx(ui32 activation, ui64 revolvingCounter) {
- if constexpr (NFeatures::IsLocalQueues()) {
- ScheduleActivationExLocalQueue(activation, revolvingCounter);
- } else {
- ScheduleActivationExCommon(activation, revolvingCounter, AtomicGet(Semaphore));
- }
- }
-
- void TBasicExecutorPool::GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const {
- poolStats.MaxUtilizationTime = RelaxedLoad(&MaxUtilizationAccumulator) / (i64)(NHPTimer::GetCyclesPerSecond() / 1000);
- poolStats.WrongWakenedThreadCount = RelaxedLoad(&WrongWakenedThreadCount);
- poolStats.CurrentThreadCount = RelaxedLoad(&ThreadCount);
- poolStats.DefaultThreadCount = DefaultThreadCount;
- poolStats.MaxThreadCount = MaxThreadCount;
- poolStats.SpinningTimeUs = Ts2Us(SpinningTimeUs);
- poolStats.SpinThresholdUs = Ts2Us(SpinThresholdCycles);
- if (Harmonizer) {
- TPoolHarmonizerStats stats = Harmonizer->GetPoolStats(PoolId);
- poolStats.IsNeedy = stats.IsNeedy;
- poolStats.IsStarved = stats.IsStarved;
- poolStats.IsHoggish = stats.IsHoggish;
- poolStats.IncreasingThreadsByNeedyState = stats.IncreasingThreadsByNeedyState;
- poolStats.IncreasingThreadsByExchange = stats.IncreasingThreadsByExchange;
- poolStats.DecreasingThreadsByStarvedState = stats.DecreasingThreadsByStarvedState;
- poolStats.DecreasingThreadsByHoggishState = stats.DecreasingThreadsByHoggishState;
- poolStats.DecreasingThreadsByExchange = stats.DecreasingThreadsByExchange;
- poolStats.PotentialMaxThreadCount = stats.PotentialMaxThreadCount;
- poolStats.MaxConsumedCpuUs = stats.MaxConsumedCpu;
- poolStats.MinConsumedCpuUs = stats.MinConsumedCpu;
- poolStats.MaxBookedCpuUs = stats.MaxBookedCpu;
- poolStats.MinBookedCpuUs = stats.MinBookedCpu;
- }
-
- statsCopy.resize(PoolThreads + 1);
- // Save counters from the pool object
- statsCopy[0] = TExecutorThreadStats();
- statsCopy[0].Aggregate(Stats);
-#if defined(ACTORSLIB_COLLECT_EXEC_STATS)
- RecalculateStuckActors(statsCopy[0]);
-#endif
- // Per-thread stats
- for (i16 i = 0; i < PoolThreads; ++i) {
- Threads[i].Thread->GetCurrentStats(statsCopy[i + 1]);
- }
- }
-
- void TBasicExecutorPool::Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) {
- TAffinityGuard affinityGuard(Affinity());
-
- ActorSystem = actorSystem;
-
- ScheduleReaders.Reset(new NSchedulerQueue::TReader[PoolThreads]);
- ScheduleWriters.Reset(new NSchedulerQueue::TWriter[PoolThreads]);
-
- for (i16 i = 0; i != PoolThreads; ++i) {
- if (i < MaxThreadCount - SharedExecutorsCount) {
- Threads[i].Thread.Reset(
- new TExecutorThread(
- i,
- 0, // CpuId is not used in BASIC pool
- actorSystem,
- this,
- MailboxTable.Get(),
- PoolName,
- TimePerMailbox,
- EventsPerMailbox));
- } else {
- Threads[i].Thread.Reset(
- new TExecutorThread(
- i,
- actorSystem,
- actorSystem->GetBasicExecutorPools(),
- PoolName,
- SoftProcessingDurationTs,
- TimePerMailbox,
- EventsPerMailbox));
- }
- ScheduleWriters[i].Init(ScheduleReaders[i]);
- }
-
- *scheduleReaders = ScheduleReaders.Get();
- *scheduleSz = PoolThreads;
- }
-
- void TBasicExecutorPool::Start() {
- TAffinityGuard affinityGuard(Affinity());
-
- ThreadUtilization = 0;
- AtomicAdd(MaxUtilizationCounter, -(i64)GetCycleCountFast());
-
- for (i16 i = 0; i != PoolThreads; ++i) {
- Threads[i].Thread->Start();
- }
- }
-
- void TBasicExecutorPool::PrepareStop() {
- AtomicStore(&StopFlag, true);
- for (i16 i = 0; i != PoolThreads; ++i) {
- Threads[i].Thread->StopFlag = true;
- Threads[i].WaitingPad.Interrupt();
- }
- }
-
- void TBasicExecutorPool::Shutdown() {
- for (i16 i = 0; i != PoolThreads; ++i)
- Threads[i].Thread->Join();
- }
-
- void TBasicExecutorPool::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) {
- Y_DEBUG_ABORT_UNLESS(workerId < PoolThreads);
-
- Schedule(deadline - ActorSystem->Timestamp(), ev, cookie, workerId);
- }
-
- void TBasicExecutorPool::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) {
- Y_DEBUG_ABORT_UNLESS(workerId < PoolThreads);
-
- const auto current = ActorSystem->Monotonic();
- if (deadline < current)
- deadline = current;
-
- ScheduleWriters[workerId].Push(deadline.MicroSeconds(), ev.Release(), cookie);
- }
-
- void TBasicExecutorPool::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) {
- Y_DEBUG_ABORT_UNLESS(workerId < PoolThreads);
-
- const auto deadline = ActorSystem->Monotonic() + delta;
- ScheduleWriters[workerId].Push(deadline.MicroSeconds(), ev.Release(), cookie);
- }
-
- void TBasicExecutorPool::SetRealTimeMode() const {
-// 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_)
- if (RealtimePriority != 0) {
- pthread_t threadSelf = pthread_self();
- sched_param param = {RealtimePriority};
- if (pthread_setschedparam(threadSelf, SCHED_FIFO, &param)) {
- Y_ABORT("Cannot set realtime priority");
- }
- }
-#else
- Y_UNUSED(RealtimePriority);
-#endif
- }
-
- i16 TBasicExecutorPool::GetThreadCount() const {
- return AtomicGet(ThreadCount);
- }
-
- void TBasicExecutorPool::SetThreadCount(i16 threads) {
- threads = Max(i16(1), Min(PoolThreads, threads));
- with_lock (ChangeThreadsLock) {
- i16 prevCount = GetThreadCount();
- AtomicSet(ThreadCount, threads);
- TSemaphore semaphore = TSemaphore::GetSemaphore(AtomicGet(Semaphore));
- i64 oldX = semaphore.ConverToI64();
- semaphore.CurrentThreadCount = threads;
- if (threads > prevCount) {
- semaphore.CurrentSleepThreadCount += (i64)threads - prevCount;
- } else {
- semaphore.CurrentSleepThreadCount -= (i64)prevCount - threads;
- }
- AtomicAdd(Semaphore, semaphore.ConverToI64() - oldX);
- LWPROBE(ThreadCount, PoolId, PoolName, threads, MinThreadCount, MaxThreadCount, DefaultThreadCount);
- }
- }
-
- i16 TBasicExecutorPool::GetDefaultThreadCount() const {
- return DefaultThreadCount;
- }
-
- i16 TBasicExecutorPool::GetMinThreadCount() const {
- return MinThreadCount;
- }
-
- i16 TBasicExecutorPool::GetMaxThreadCount() const {
- return MaxThreadCount;
- }
-
- TCpuConsumption TBasicExecutorPool::GetThreadCpuConsumption(i16 threadIdx) {
- if (threadIdx >= PoolThreads) {
- return {0.0, 0.0};
- }
- TThreadCtx& threadCtx = Threads[threadIdx];
- TExecutorThreadStats stats;
- threadCtx.Thread->GetCurrentStats(stats);
- return {Ts2Us(stats.SafeElapsedTicks), static_cast<double>(stats.CpuUs), stats.NotEnoughCpuExecutions};
- }
-
- i16 TBasicExecutorPool::GetBlockingThreadCount() const {
- TAtomic x = AtomicGet(Semaphore);
- TSemaphore semaphore = TSemaphore::GetSemaphore(x);
- return -Min<i16>(semaphore.CurrentSleepThreadCount, 0);
- }
-
- i16 TBasicExecutorPool::GetPriority() const {
- return Priority;
- }
-
- void TBasicExecutorPool::SetSharedExecutorsCount(i16 count) {
- SharedExecutorsCount = count;
- }
-
- void TBasicExecutorPool::SetLocalQueueSize(ui16 size) {
- if constexpr (!NFeatures::TLocalQueuesFeatureFlags::FIXED_LOCAL_QUEUE_SIZE) {
- LocalQueueSize.store(std::max(size, NFeatures::TLocalQueuesFeatureFlags::MAX_LOCAL_QUEUE_SIZE), std::memory_order_relaxed);
- }
- }
-
- void TBasicExecutorPool::Initialize(TWorkerContext& wctx) {
- if (wctx.WorkerId >= 0) {
- TlsThreadContext->WaitingStats = &WaitingStats[wctx.WorkerId];
- }
- }
-
- void TBasicExecutorPool::SetSpinThresholdCycles(ui32 cycles) {
- if (ActorSystemProfile == EASProfile::LowLatency) {
- if (DefaultSpinThresholdCycles > cycles) {
- cycles = DefaultSpinThresholdCycles;
- }
- }
- SpinThresholdCycles = cycles;
- double resolutionUs = TWaitingStatsConstants::HistogramResolutionUs;
- ui32 bucketIdx = cycles / TWaitingStatsConstants::HistogramResolution;
- LWPROBE(ChangeSpinThreshold, PoolId, PoolName, cycles, resolutionUs * bucketIdx, bucketIdx);
- }
-
- void TBasicExecutorPool::GetWaitingStats(TWaitingStats<ui64> &acc) const {
- acc.Clear();
- double resolutionUs = TWaitingStatsConstants::HistogramResolutionUs;
- for (ui32 idx = 0; idx < ThreadCount; ++idx) {
- for (ui32 bucketIdx = 0; bucketIdx < TWaitingStatsConstants::BucketCount; ++bucketIdx) {
- LWPROBE(WaitingHistogramPerThread, PoolId, PoolName, idx, resolutionUs * bucketIdx, resolutionUs * (bucketIdx + 1), WaitingStats[idx].WaitingUntilNeedsTimeHist[bucketIdx].load());
- }
- acc.Add(WaitingStats[idx]);
- }
- for (ui32 bucketIdx = 0; bucketIdx < TWaitingStatsConstants::BucketCount; ++bucketIdx) {
- LWPROBE(WaitingHistogram, PoolId, PoolName, resolutionUs * bucketIdx, resolutionUs * (bucketIdx + 1), acc.WaitingUntilNeedsTimeHist[bucketIdx].load());
- }
- }
-
- void TBasicExecutorPool::ClearWaitingStats() const {
- for (ui32 idx = 0; idx < ThreadCount; ++idx) {
- WaitingStats[idx].Clear();
- }
- }
-
- void TBasicExecutorPool::CalcSpinPerThread(ui64 wakingUpConsumption) {
- for (i16 threadIdx = 0; threadIdx < PoolThreads; ++threadIdx) {
- ui64 newSpinThreshold = 0;
- if constexpr (NFeatures::TSpinFeatureFlags::UsePseudoMovingWindow) {
- MovingWaitingStats[threadIdx].Add(WaitingStats[threadIdx], 0.8, 0.2);
- newSpinThreshold = MovingWaitingStats[threadIdx].CalculateGoodSpinThresholdCycles(wakingUpConsumption);
- } else {
- newSpinThreshold = WaitingStats[threadIdx].CalculateGoodSpinThresholdCycles(wakingUpConsumption);
- }
- SpinThresholdCyclesPerThread[threadIdx].store(newSpinThreshold);
-
- double resolutionUs = TWaitingStatsConstants::HistogramResolutionUs;
- ui32 bucketIdx = newSpinThreshold / TWaitingStatsConstants::HistogramResolution;
- LWPROBE(ChangeSpinThresholdPerThread, PoolId, PoolName, threadIdx, newSpinThreshold, resolutionUs * bucketIdx, bucketIdx);
- }
- }
-}
diff --git a/library/cpp/actors/core/executor_pool_basic.h b/library/cpp/actors/core/executor_pool_basic.h
deleted file mode 100644
index d1a4c9fd27..0000000000
--- a/library/cpp/actors/core/executor_pool_basic.h
+++ /dev/null
@@ -1,291 +0,0 @@
-#pragma once
-
-#include "actorsystem.h"
-#include "executor_thread.h"
-#include "executor_pool_basic_feature_flags.h"
-#include "scheduler_queue.h"
-#include "executor_pool_base.h"
-#include "harmonizer.h"
-#include <library/cpp/actors/actor_type/indexes.h>
-#include <library/cpp/actors/util/unordered_cache.h>
-#include <library/cpp/actors/util/threadparkpad.h>
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-#include <library/cpp/threading/chunk_queue/queue.h>
-
-#include <util/system/mutex.h>
-
-#include <queue>
-
-namespace NActors {
-
- struct TWaitingStatsConstants {
- static constexpr ui64 BucketCount = 128;
- static constexpr double MaxSpinThersholdUs = 12.8;
-
- static constexpr ui64 KnownAvgWakingUpTime = 4250;
- static constexpr ui64 KnownAvgAwakeningTime = 7000;
-
- static const double HistogramResolutionUs;
- static const ui64 HistogramResolution;
- };
-
- template <typename T>
- struct TWaitingStats : TWaitingStatsConstants {
- std::array<std::atomic<T>, BucketCount> WaitingUntilNeedsTimeHist;
-
- std::atomic<T> WakingUpTotalTime;
- std::atomic<T> WakingUpCount;
- std::atomic<T> AwakingTotalTime;
- std::atomic<T> AwakingCount;
-
- TWaitingStats()
- {
- Clear();
- }
-
- void Clear() {
- std::fill(WaitingUntilNeedsTimeHist.begin(), WaitingUntilNeedsTimeHist.end(), 0);
- WakingUpTotalTime = 0;
- WakingUpCount = 0;
- AwakingTotalTime = 0;
- AwakingCount = 0;
- }
-
- void Add(ui64 waitingUntilNeedsTime) {
- ui64 waitIdx = std::min(waitingUntilNeedsTime / HistogramResolution, BucketCount - 1);
- WaitingUntilNeedsTimeHist[waitIdx]++;
- }
-
- void AddAwakening(ui64 waitingUntilNeedsTime, ui64 awakingTime) {
- Add(waitingUntilNeedsTime);
- AwakingTotalTime += awakingTime;
- AwakingCount++;
- }
-
- void AddFastAwakening(ui64 waitingUntilNeedsTime) {
- Add(waitingUntilNeedsTime - HistogramResolution);
- }
-
- void AddWakingUp(ui64 wakingUpTime) {
- WakingUpTotalTime += wakingUpTime;
- WakingUpCount++;
- }
-
- void Add(const TWaitingStats<T> &stats) {
- for (ui32 idx = 0; idx < BucketCount; ++idx) {
- WaitingUntilNeedsTimeHist[idx] += stats.WaitingUntilNeedsTimeHist[idx];
- }
- WakingUpTotalTime += stats.WakingUpTotalTime;
- WakingUpCount += stats.WakingUpCount;
- AwakingTotalTime += stats.AwakingTotalTime;
- AwakingCount += stats.AwakingCount;
- }
-
- template <typename T2>
- void Add(const TWaitingStats<T2> &stats, double oldK, double newK) {
- for (ui32 idx = 0; idx < BucketCount; ++idx) {
- WaitingUntilNeedsTimeHist[idx] = oldK * WaitingUntilNeedsTimeHist[idx] + newK * stats.WaitingUntilNeedsTimeHist[idx];
- }
- WakingUpTotalTime = oldK * WakingUpTotalTime + newK * stats.WakingUpTotalTime;
- WakingUpCount = oldK * WakingUpCount + newK * stats.WakingUpCount;
- AwakingTotalTime = oldK * AwakingTotalTime + newK * stats.AwakingTotalTime;
- AwakingCount = oldK * AwakingCount + newK * stats.AwakingCount;
- }
-
- ui32 CalculateGoodSpinThresholdCycles(ui64 avgWakingUpConsumption) {
- auto &bucketCount = TWaitingStatsConstants::BucketCount;
- auto &resolution = TWaitingStatsConstants::HistogramResolution;
-
- T waitingsCount = std::accumulate(WaitingUntilNeedsTimeHist.begin(), WaitingUntilNeedsTimeHist.end(), 0);
-
- ui32 bestBucketIdx = 0;
- T bestCpuConsumption = Max<T>();
-
- T spinTime = 0;
- T spinCount = 0;
-
- for (ui32 bucketIdx = 0; bucketIdx < bucketCount; ++bucketIdx) {
- auto &bucket = WaitingUntilNeedsTimeHist[bucketIdx];
- ui64 imaginarySpingThreshold = resolution * bucketIdx;
- T cpuConsumption = spinTime + (waitingsCount - spinCount) * (avgWakingUpConsumption + imaginarySpingThreshold);
- if (bestCpuConsumption > cpuConsumption) {
- bestCpuConsumption = cpuConsumption;
- bestBucketIdx = bucketIdx;
- }
- spinTime += (2 * imaginarySpingThreshold + resolution) * bucket / 2;
- spinCount += bucket;
- // LWPROBE(WaitingHistogram, Pool->PoolId, Pool->GetName(), resolutionUs * bucketIdx, resolutionUs * (bucketIdx + 1), bucket);
- }
- ui64 result = resolution * bestBucketIdx;
- return result;
- }
- };
-
- class TBasicExecutorPool: public TExecutorPoolBase {
- struct TThreadCtx {
- TAutoPtr<TExecutorThread> Thread;
- TThreadParkPad WaitingPad;
- TAtomic WaitingFlag;
- std::atomic<i64> StartWakingTs;
- std::atomic<i64> EndWakingTs;
-
- enum EWaitState {
- WS_NONE,
- WS_ACTIVE,
- WS_BLOCKED,
- WS_RUNNING
- };
-
- TThreadCtx()
- : WaitingFlag(WS_NONE)
- {
- }
- };
-
- struct TTimers {
- NHPTimer::STime Elapsed = 0;
- NHPTimer::STime Parked = 0;
- NHPTimer::STime HPStart = GetCycleCountFast();
- NHPTimer::STime HPNow;
- };
-
- NThreading::TPadded<std::atomic_bool> AllThreadsSleep = true;
- const ui64 DefaultSpinThresholdCycles;
- std::atomic<ui64> SpinThresholdCycles;
- std::unique_ptr<NThreading::TPadded< std::atomic<ui64>>[]> SpinThresholdCyclesPerThread;
-
- TArrayHolder<NThreading::TPadded<TThreadCtx>> Threads;
- static_assert(sizeof(std::decay_t<decltype(Threads[0])>) == PLATFORM_CACHE_LINE);
- TArrayHolder<NThreading::TPadded<std::queue<ui32>>> LocalQueues;
- TArrayHolder<TWaitingStats<ui64>> WaitingStats;
- TArrayHolder<TWaitingStats<double>> MovingWaitingStats;
- std::atomic<ui16> LocalQueueSize;
-
-
- TArrayHolder<NSchedulerQueue::TReader> ScheduleReaders;
- TArrayHolder<NSchedulerQueue::TWriter> ScheduleWriters;
-
- const TString PoolName;
- const TDuration TimePerMailbox;
- const ui32 EventsPerMailbox;
- EASProfile ActorSystemProfile;
-
- const int RealtimePriority;
-
- TAtomic ThreadUtilization;
- TAtomic MaxUtilizationCounter;
- TAtomic MaxUtilizationAccumulator;
- TAtomic WrongWakenedThreadCount;
- std::atomic<ui64> SpinningTimeUs;
-
- TAtomic ThreadCount;
- TMutex ChangeThreadsLock;
-
- i16 MinThreadCount;
- i16 MaxThreadCount;
- i16 DefaultThreadCount;
- IHarmonizer *Harmonizer;
- i16 SharedExecutorsCount = 0;
- ui64 SoftProcessingDurationTs = 0;
-
- const i16 Priority = 0;
- const ui32 ActorSystemIndex = NActors::TActorTypeOperator::GetActorSystemIndex();
- public:
- struct TSemaphore {
- i64 OldSemaphore = 0; // 34 bits
- // Sign bit
- i16 CurrentSleepThreadCount = 0; // 14 bits
- // Sign bit
- i16 CurrentThreadCount = 0; // 14 bits
-
- inline i64 ConverToI64() {
- i64 value = (1ll << 34) + OldSemaphore;
- return value
- | (((i64)CurrentSleepThreadCount + (1 << 14)) << 35)
- | ((i64)CurrentThreadCount << 50);
- }
-
- static inline TSemaphore GetSemaphore(i64 value) {
- TSemaphore semaphore;
- semaphore.OldSemaphore = (value & 0x7ffffffffll) - (1ll << 34);
- semaphore.CurrentSleepThreadCount = ((value >> 35) & 0x7fff) - (1 << 14);
- semaphore.CurrentThreadCount = (value >> 50) & 0x3fff;
- return semaphore;
- }
- };
-
- static constexpr TDuration DEFAULT_TIME_PER_MAILBOX = TBasicExecutorPoolConfig::DEFAULT_TIME_PER_MAILBOX;
- static constexpr ui32 DEFAULT_EVENTS_PER_MAILBOX = TBasicExecutorPoolConfig::DEFAULT_EVENTS_PER_MAILBOX;
-
- TBasicExecutorPool(ui32 poolId,
- ui32 threads,
- ui64 spinThreshold,
- const TString& poolName = "",
- IHarmonizer *harmonizer = nullptr,
- TAffinity* affinity = nullptr,
- TDuration timePerMailbox = DEFAULT_TIME_PER_MAILBOX,
- ui32 eventsPerMailbox = DEFAULT_EVENTS_PER_MAILBOX,
- int realtimePriority = 0,
- ui32 maxActivityType = 0 /* deprecated */,
- i16 minThreadCount = 0,
- i16 maxThreadCount = 0,
- i16 defaultThreadCount = 0,
- i16 priority = 0);
- explicit TBasicExecutorPool(const TBasicExecutorPoolConfig& cfg, IHarmonizer *harmonizer);
- ~TBasicExecutorPool();
-
- void SetSharedExecutorsCount(i16 count);
-
- void Initialize(TWorkerContext& wctx) override;
- ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingReadCounter) override;
- ui32 GetReadyActivationCommon(TWorkerContext& wctx, ui64 revolvingReadCounter);
- ui32 GetReadyActivationLocalQueue(TWorkerContext& wctx, ui64 revolvingReadCounter);
-
- void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override;
- void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override;
- void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override;
-
- void ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) override;
- void ScheduleActivationExCommon(ui32 activation, ui64 revolvingWriteCounter, TAtomic semaphoreValue);
- void ScheduleActivationExLocalQueue(ui32 activation, ui64 revolvingWriteCounter);
-
- void SetLocalQueueSize(ui16 size);
-
- void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) override;
- void Start() override;
- void PrepareStop() override;
- void Shutdown() override;
-
- void GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const override;
- TString GetName() const override {
- return PoolName;
- }
-
- void SetRealTimeMode() const override;
-
- i16 GetThreadCount() const override;
- void SetThreadCount(i16 threads) override;
- i16 GetDefaultThreadCount() const override;
- i16 GetMinThreadCount() const override;
- i16 GetMaxThreadCount() const override;
- TCpuConsumption GetThreadCpuConsumption(i16 threadIdx) override;
- i16 GetBlockingThreadCount() const override;
- i16 GetPriority() const override;
-
- void SetSpinThresholdCycles(ui32 cycles) override;
-
- void GetWaitingStats(TWaitingStats<ui64> &acc) const;
- void CalcSpinPerThread(ui64 wakingUpConsumption);
- void ClearWaitingStats() const;
-
- private:
- void AskToGoToSleep(bool *needToWait, bool *needToBlock);
-
- void WakeUpLoop(i16 currentThreadCount);
- bool GoToWaiting(TThreadCtx& threadCtx, TTimers &timers, bool needToBlock);
- ui32 GoToSpin(TThreadCtx& threadCtx, i64 start, i64 &end);
- bool GoToSleep(TThreadCtx& threadCtx, TTimers &timers);
- bool GoToBeBlocked(TThreadCtx& threadCtx, TTimers &timers);
- };
-}
diff --git a/library/cpp/actors/core/executor_pool_basic_feature_flags.h b/library/cpp/actors/core/executor_pool_basic_feature_flags.h
deleted file mode 100644
index 17f2a81df4..0000000000
--- a/library/cpp/actors/core/executor_pool_basic_feature_flags.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-#include <optional>
-
-
-namespace NActors::NFeatures {
-
- enum class EActorSystemOptimizationType {
- Common,
- LocalQueues,
- };
-
- struct TCommonFeatureFlags {
- static constexpr EActorSystemOptimizationType OptimizationType = EActorSystemOptimizationType::Common;
-
- static constexpr bool ProbeSpinCycles = false;
- };
-
- struct TLocalQueuesFeatureFlags {
- static constexpr EActorSystemOptimizationType OptimizationType = EActorSystemOptimizationType::LocalQueues;
-
- static constexpr ui16 MIN_LOCAL_QUEUE_SIZE = 0;
- static constexpr ui16 MAX_LOCAL_QUEUE_SIZE = 16;
- static constexpr std::optional<ui16> FIXED_LOCAL_QUEUE_SIZE = std::nullopt;
-
- static constexpr bool UseIfAllOtherThreadsAreSleeping = false;
- static constexpr bool UseOnMicroburst = false;
- };
-
- struct TSpinFeatureFlags {
- static constexpr bool DoNotSpinLower = false;
- static constexpr bool UsePseudoMovingWindow = true;
-
- static constexpr bool HotColdThreads = false;
- static constexpr bool CalcPerThread = false;
- };
-
- using TFeatureFlags = TCommonFeatureFlags;
-
- consteval bool IsCommon() {
- return TFeatureFlags::OptimizationType == EActorSystemOptimizationType::Common;
- }
-
- consteval bool IsLocalQueues() {
- return TFeatureFlags::OptimizationType == EActorSystemOptimizationType::LocalQueues;
- }
-
-}
diff --git a/library/cpp/actors/core/executor_pool_basic_ut.cpp b/library/cpp/actors/core/executor_pool_basic_ut.cpp
deleted file mode 100644
index df8df52635..0000000000
--- a/library/cpp/actors/core/executor_pool_basic_ut.cpp
+++ /dev/null
@@ -1,666 +0,0 @@
-#include "actorsystem.h"
-#include "executor_pool_basic.h"
-#include "hfunc.h"
-#include "scheduler_basic.h"
-
-#include <library/cpp/actors/util/should_continue.h>
-
-#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NActors;
-
-#define VALUES_EQUAL(a, b, ...) \
- UNIT_ASSERT_VALUES_EQUAL_C((a), (b), (i64)semaphore.OldSemaphore \
- << ' ' << (i64)semaphore.CurrentSleepThreadCount \
- << ' ' << (i64)semaphore.CurrentThreadCount __VA_ARGS__);
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct TEvMsg : public NActors::TEventBase<TEvMsg, 10347> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvMsg, "ExecutorPoolTest: Msg");
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-class TTestSenderActor : public IActorCallback {
-private:
- using EActivityType = IActor::EActivityType ;
- using EActorActivity = IActor::EActorActivity;
-
-private:
- TAtomic Counter;
- TActorId Receiver;
-
- std::function<void(void)> Action;
-
-public:
- TTestSenderActor(std::function<void(void)> action = [](){},
- EActivityType activityType = EActorActivity::OTHER)
- : IActorCallback(static_cast<TReceiveFunc>(&TTestSenderActor::Execute), activityType)
- , Action(action)
- {}
-
- void Start(TActorId receiver, size_t count)
- {
- AtomicSet(Counter, count);
- Receiver = receiver;
- }
-
- void Stop() {
- while (true) {
- if (GetCounter() == 0) {
- break;
- }
-
- Sleep(TDuration::MilliSeconds(1));
- }
- }
-
- size_t GetCounter() const {
- return AtomicGet(Counter);
- }
-
-private:
- STFUNC(Execute)
- {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvMsg, Handle);
- }
- }
-
- void Handle(TEvMsg::TPtr &ev)
- {
- Y_UNUSED(ev);
- Action();
- TAtomicBase count = AtomicDecrement(Counter);
- Y_ABORT_UNLESS(count != Max<TAtomicBase>());
- if (count) {
- Send(Receiver, new TEvMsg());
- }
- }
-};
-
-THolder<TActorSystemSetup> GetActorSystemSetup(TBasicExecutorPool* pool)
-{
- auto setup = MakeHolder<NActors::TActorSystemSetup>();
- setup->NodeId = 1;
- setup->ExecutorsCount = 1;
- setup->Executors.Reset(new TAutoPtr<NActors::IExecutorPool>[1]);
- setup->Executors[0] = pool;
- setup->Scheduler = new TBasicSchedulerThread(NActors::TSchedulerConfig(512, 0));
- return setup;
-}
-
-Y_UNIT_TEST_SUITE(WaitingBenchs) {
-
- Y_UNIT_TEST(SpinPause) {
- const ui32 count = 1'000'000;
- ui64 startTs = GetCycleCountFast();
- for (ui32 idx = 0; idx < count; ++idx) {
- SpinLockPause();
- }
- ui64 stopTs = GetCycleCountFast();
- Cerr << Ts2Us(stopTs - startTs) / count << Endl;
- Cerr << double(stopTs - startTs) / count << Endl;
- }
-
- struct TThread : public ISimpleThread {
- static const ui64 CyclesInMicroSecond;
- std::array<ui64, 128> Hist;
- ui64 WakingTime = 0;
- ui64 AwakeningTime = 0;
- ui64 SleepTime = 0;
- ui64 IterationCount = 0;
-
- std::atomic<ui64> Awakens = 0;
- std::atomic<ui64> *OtherAwaken;
-
- TThreadParkPad OwnPad;
- TThreadParkPad *OtherPad;
-
- bool IsWaiting = false;
-
- void GoToWait() {
- ui64 start = GetCycleCountFast();
- OwnPad.Park();
- ui64 elapsed = GetCycleCountFast() - start;
- AwakeningTime += elapsed;
- ui64 idx = std::min(Hist.size() - 1, (elapsed - 20 * CyclesInMicroSecond) / CyclesInMicroSecond);
- Hist[idx]++;
- Awakens++;
- }
-
- void GoToWakeUp() {
- ui64 start = GetCycleCountFast();
- OtherPad->Unpark();
- ui64 elapsed = GetCycleCountFast() - start;
- WakingTime += elapsed;
- ui64 idx = std::min(Hist.size() - 1, elapsed / CyclesInMicroSecond);
- Hist[idx]++;
- }
-
- void GoToSleep() {
- ui64 start = GetCycleCountFast();
- ui64 stop = start;
- while (stop - start < 20 * CyclesInMicroSecond) {
- SpinLockPause();
- stop = GetCycleCountFast();
- }
- SleepTime += stop - start;
- }
-
- void* ThreadProc() {
- for (ui32 idx = 0; idx < IterationCount; ++idx) {
- if (IsWaiting) {
- GoToWait();
- } else {
- GoToSleep();
- GoToWakeUp();
- while(OtherAwaken->load() == idx) {
- SpinLockPause();
- }
- }
- }
- return nullptr;
- }
- };
-
- const ui64 TThread::CyclesInMicroSecond = NHPTimer::GetCyclesPerSecond() * 0.000001;
-
- Y_UNIT_TEST(WakingUpTest) {
- TThread a, b;
- constexpr ui64 iterations = 100'000;
- std::fill(a.Hist.begin(), a.Hist.end(), 0);
- std::fill(b.Hist.begin(), b.Hist.end(), 0);
- a.IterationCount = iterations;
- b.IterationCount = iterations;
- a.IsWaiting = true;
- b.IsWaiting = false;
- b.OtherAwaken = &a.Awakens;
- a.OtherPad = &b.OwnPad;
- b.OtherPad = &a.OwnPad;
- a.Start();
- b.Start();
- a.Join();
- b.Join();
-
- ui64 awakeningTime = a.AwakeningTime + b.AwakeningTime - a.SleepTime - b.SleepTime;
- ui64 wakingUpTime = a.WakingTime + b.WakingTime;
-
- Cerr << "AvgAwakeningCycles: " << double(awakeningTime) / iterations << Endl;
- Cerr << "AvgAwakeningUs: " << Ts2Us(awakeningTime) / iterations << Endl;
- Cerr << "AvgSleep20usCycles:" << double(b.SleepTime) / iterations << Endl;
- Cerr << "AvgSleep20usUs:" << Ts2Us(b.SleepTime) / iterations << Endl;
- Cerr << "AvgWakingUpCycles: " << double(wakingUpTime) / iterations << Endl;
- Cerr << "AvgWakingUpUs: " << Ts2Us(wakingUpTime) / iterations << Endl;
-
- Cerr << "AwakeningHist:\n";
- for (ui32 idx = 0; idx < a.Hist.size(); ++idx) {
- if (a.Hist[idx]) {
- if (idx + 1 != a.Hist.size()) {
- Cerr << " [" << idx << "us - " << idx + 1 << "us] " << a.Hist[idx] << Endl;
- } else {
- Cerr << " [" << idx << "us - ...] " << a.Hist[idx] << Endl;
- }
- }
- }
-
- Cerr << "WakingUpHist:\n";
- for (ui32 idx = 0; idx < b.Hist.size(); ++idx) {
- if (b.Hist[idx]) {
- if (idx + 1 != b.Hist.size()) {
- Cerr << " [" << idx << "us - " << idx + 1 << "us] " << b.Hist[idx] << Endl;
- } else {
- Cerr << " [" << idx << "us - ...] " << b.Hist[idx] << Endl;
- }
- }
- }
- }
-
-}
-
-Y_UNIT_TEST_SUITE(BasicExecutorPool) {
-
- Y_UNIT_TEST(Semaphore) {
- TBasicExecutorPool::TSemaphore semaphore;
- semaphore = TBasicExecutorPool::TSemaphore::GetSemaphore(0);
-
- VALUES_EQUAL(0, semaphore.ConverToI64());
- semaphore = TBasicExecutorPool::TSemaphore::GetSemaphore(-1);
- VALUES_EQUAL(-1, semaphore.ConverToI64());
- semaphore = TBasicExecutorPool::TSemaphore::GetSemaphore(1);
- VALUES_EQUAL(1, semaphore.ConverToI64());
-
- for (i64 value = -1'000'000; value <= 1'000'000; ++value) {
- VALUES_EQUAL(TBasicExecutorPool::TSemaphore::GetSemaphore(value).ConverToI64(), value);
- }
-
- for (i8 sleepThreads = -10; sleepThreads <= 10; ++sleepThreads) {
-
- semaphore = TBasicExecutorPool::TSemaphore();
- semaphore.CurrentSleepThreadCount = sleepThreads;
- i64 initialValue = semaphore.ConverToI64();
-
- semaphore = TBasicExecutorPool::TSemaphore::GetSemaphore(initialValue - 1);
- VALUES_EQUAL(-1, semaphore.OldSemaphore);
-
- i64 value = initialValue;
- value -= 100;
- for (i32 expected = -100; expected <= 100; ++expected) {
- semaphore = TBasicExecutorPool::TSemaphore::GetSemaphore(value);
- UNIT_ASSERT_VALUES_EQUAL_C(expected, semaphore.OldSemaphore, (i64)semaphore.OldSemaphore
- << ' ' << (i64)semaphore.CurrentSleepThreadCount
- << ' ' << (i64)semaphore.CurrentThreadCount);
- UNIT_ASSERT_VALUES_EQUAL_C(sleepThreads, semaphore.CurrentSleepThreadCount, (i64)semaphore.OldSemaphore
- << ' ' << (i64)semaphore.CurrentSleepThreadCount
- << ' ' << (i64)semaphore.CurrentThreadCount);
- semaphore = TBasicExecutorPool::TSemaphore();
- semaphore.OldSemaphore = expected;
- semaphore.CurrentSleepThreadCount = sleepThreads;
- UNIT_ASSERT_VALUES_EQUAL(semaphore.ConverToI64(), value);
- value++;
- }
-
- for (i32 expected = 101; expected >= -101; --expected) {
- semaphore = TBasicExecutorPool::TSemaphore::GetSemaphore(value);
- UNIT_ASSERT_VALUES_EQUAL_C(expected, semaphore.OldSemaphore, (i64)semaphore.OldSemaphore
- << ' ' << (i64)semaphore.CurrentSleepThreadCount
- << ' ' << (i64)semaphore.CurrentThreadCount);
- UNIT_ASSERT_VALUES_EQUAL_C(sleepThreads, semaphore.CurrentSleepThreadCount, (i64)semaphore.OldSemaphore
- << ' ' << (i64)semaphore.CurrentSleepThreadCount
- << ' ' << (i64)semaphore.CurrentThreadCount);
- value--;
- }
- }
-
- //UNIT_ASSERT_VALUES_EQUAL_C(-1, TBasicExecutorPool::TSemaphore::GetSemaphore(value-1).OldSemaphore);
- }
-
- Y_UNIT_TEST(CheckCompleteOne) {
- const size_t size = 4;
- const size_t msgCount = 1e4;
- TBasicExecutorPool* executorPool = new TBasicExecutorPool(0, size, 50);
-
- auto setup = GetActorSystemSetup(executorPool);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- auto begin = TInstant::Now();
-
- auto actor = new TTestSenderActor();
- auto actorId = actorSystem.Register(actor);
- actor->Start(actor->SelfId(), msgCount);
- actorSystem.Send(actorId, new TEvMsg());
-
- while (actor->GetCounter()) {
- auto now = TInstant::Now();
- UNIT_ASSERT_C(now - begin < TDuration::Seconds(5), "Counter is " << actor->GetCounter());
-
- Sleep(TDuration::MilliSeconds(1));
- }
- }
-
- Y_UNIT_TEST(CheckCompleteAll) {
- const size_t size = 4;
- const size_t msgCount = 1e4;
- TBasicExecutorPool* executorPool = new TBasicExecutorPool(0, size, 50);
-
- auto setup = GetActorSystemSetup(executorPool);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- auto begin = TInstant::Now();
-
- TTestSenderActor* actors[size];
- TActorId actorIds[size];
-
- for (size_t i = 0; i < size; ++i) {
- actors[i] = new TTestSenderActor();
- actorIds[i] = actorSystem.Register(actors[i]);
- }
- for (size_t i = 0; i < size; ++i) {
- actors[i]->Start(actors[i]->SelfId(), msgCount);
- }
- for (size_t i = 0; i < size; ++i) {
- actorSystem.Send(actorIds[i], new TEvMsg());
- }
-
-
- while (true) {
- size_t maxCounter = 0;
- for (size_t i = 0; i < size; ++i) {
- maxCounter = Max(maxCounter, actors[i]->GetCounter());
- }
-
- if (maxCounter == 0) {
- break;
- }
-
- auto now = TInstant::Now();
- UNIT_ASSERT_C(now - begin < TDuration::Seconds(5), "Max counter is " << maxCounter);
-
- Sleep(TDuration::MilliSeconds(1));
- }
- }
-
- Y_UNIT_TEST(CheckCompleteOver) {
- const size_t size = 4;
- const size_t actorsCount = size * 2;
- const size_t msgCount = 1e4;
- TBasicExecutorPool* executorPool = new TBasicExecutorPool(0, size, 50);
-
- auto setup = GetActorSystemSetup(executorPool);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- auto begin = TInstant::Now();
-
- TTestSenderActor* actors[actorsCount];
- TActorId actorIds[actorsCount];
-
- for (size_t i = 0; i < actorsCount; ++i) {
- actors[i] = new TTestSenderActor();
- actorIds[i] = actorSystem.Register(actors[i]);
- }
- for (size_t i = 0; i < actorsCount; ++i) {
- actors[i]->Start(actors[i]->SelfId(), msgCount);
- }
- for (size_t i = 0; i < actorsCount; ++i) {
- actorSystem.Send(actorIds[i], new TEvMsg());
- }
-
-
- while (true) {
- size_t maxCounter = 0;
- for (size_t i = 0; i < actorsCount; ++i) {
- maxCounter = Max(maxCounter, actors[i]->GetCounter());
- }
-
- if (maxCounter == 0) {
- break;
- }
-
- auto now = TInstant::Now();
- UNIT_ASSERT_C(now - begin < TDuration::Seconds(5), "Max counter is " << maxCounter);
-
- Sleep(TDuration::MilliSeconds(1));
- }
- }
-
- Y_UNIT_TEST(CheckCompleteRoundRobinOver) {
- const size_t size = 4;
- const size_t actorsCount = size * 2;
- const size_t msgCount = 1e2;
- TBasicExecutorPool* executorPool = new TBasicExecutorPool(0, size, 50);
-
- auto setup = GetActorSystemSetup(executorPool);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- auto begin = TInstant::Now();
-
- TTestSenderActor* actors[actorsCount];
- TActorId actorIds[actorsCount];
-
- for (size_t i = 0; i < actorsCount; ++i) {
- actors[i] = new TTestSenderActor();
- actorIds[i] = actorSystem.Register(actors[i]);
- }
- for (size_t i = 0; i < actorsCount; ++i) {
- actors[i]->Start(actorIds[(i + 1) % actorsCount], msgCount);
- }
- for (size_t i = 0; i < actorsCount; ++i) {
- actorSystem.Send(actorIds[i], new TEvMsg());
- }
-
- while (true) {
- size_t maxCounter = 0;
- for (size_t i = 0; i < actorsCount; ++i) {
- maxCounter = Max(maxCounter, actors[i]->GetCounter());
- }
-
- if (maxCounter == 0) {
- break;
- }
-
- auto now = TInstant::Now();
- UNIT_ASSERT_C(now - begin < TDuration::Seconds(5), "Max counter is " << maxCounter);
-
- Sleep(TDuration::MilliSeconds(1));
- }
- }
-
- Y_UNIT_TEST(CheckStats) {
- const size_t size = 4;
- const size_t msgCount = 1e4;
- TBasicExecutorPool* executorPool = new TBasicExecutorPool(0, size, 50);
-
- auto setup = GetActorSystemSetup(executorPool);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- auto begin = TInstant::Now();
-
- auto actor = new TTestSenderActor();
- auto actorId = actorSystem.Register(actor);
- actor->Start(actor->SelfId(), msgCount);
- actorSystem.Send(actorId, new TEvMsg());
-
- while (actor->GetCounter()) {
- auto now = TInstant::Now();
- UNIT_ASSERT_C(now - begin < TDuration::Seconds(5), "Counter is " << actor->GetCounter());
-
- Sleep(TDuration::MilliSeconds(1));
- }
-
- TVector<TExecutorThreadStats> stats;
- TExecutorPoolStats poolStats;
- actorSystem.GetPoolStats(0, poolStats, stats);
- // Sum all per-thread counters into the 0th element
- for (ui32 idx = 1; idx < stats.size(); ++idx) {
- stats[0].Aggregate(stats[idx]);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(stats[0].SentEvents, msgCount - 1);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ReceivedEvents, msgCount);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PreemptedEvents, 0);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].NonDeliveredEvents, 0);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].EmptyMailboxActivation, 0);
- //UNIT_ASSERT_VALUES_EQUAL(stats[0].CpuUs, 0); // depends on total duration of test, so undefined
- UNIT_ASSERT(stats[0].ElapsedTicks > 0);
- UNIT_ASSERT(stats[0].ParkedTicks > 0);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].BlockedTicks, 0);
- UNIT_ASSERT(stats[0].ActivationTimeHistogram.TotalSamples >= msgCount / TBasicExecutorPoolConfig::DEFAULT_EVENTS_PER_MAILBOX);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].EventDeliveryTimeHistogram.TotalSamples, msgCount);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].EventProcessingCountHistogram.TotalSamples, msgCount);
- UNIT_ASSERT(stats[0].EventProcessingTimeHistogram.TotalSamples > 0);
- UNIT_ASSERT(stats[0].ElapsedTicksByActivity[NActors::TActorTypeOperator::GetOtherActivityIndex()] > 0);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ReceivedEventsByActivity[NActors::TActorTypeOperator::GetOtherActivityIndex()], msgCount);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ActorsAliveByActivity[NActors::TActorTypeOperator::GetOtherActivityIndex()], 1);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ScheduledEventsByActivity[NActors::TActorTypeOperator::GetOtherActivityIndex()], 0);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PoolActorRegistrations, 1);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PoolDestroyedActors, 0);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PoolAllocatedMailboxes, 4095); // one line
- UNIT_ASSERT(stats[0].MailboxPushedOutByTime + stats[0].MailboxPushedOutByEventCount >= msgCount / TBasicExecutorPoolConfig::DEFAULT_EVENTS_PER_MAILBOX);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].MailboxPushedOutBySoftPreemption, 0);
- }
-}
-
-Y_UNIT_TEST_SUITE(ChangingThreadsCountInBasicExecutorPool) {
-
- struct TMockState {
- void ActorDo() {}
- };
-
- struct TTestActors {
- const size_t Count;
- TArrayHolder<TTestSenderActor*> Actors;
- TArrayHolder<TActorId> ActorIds;
-
- TTestActors(size_t count)
- : Count(count)
- , Actors(new TTestSenderActor*[count])
- , ActorIds(new TActorId[count])
- { }
-
- void Start(TActorSystem &actorSystem, size_t msgCount) {
- for (size_t i = 0; i < Count; ++i) {
- Actors[i]->Start(Actors[i]->SelfId(), msgCount);
- }
- for (size_t i = 0; i < Count; ++i) {
- actorSystem.Send(ActorIds[i], new TEvMsg());
- }
- }
-
- void Stop() {
- for (size_t i = 0; i < Count; ++i) {
- Actors[i]->Stop();
- }
- }
- };
-
- template <typename TState = TMockState>
- struct TTestCtx {
- const size_t MaxThreadCount;
- const size_t SendingMessageCount;
- std::unique_ptr<TBasicExecutorPool> ExecutorPool;
- THolder<TActorSystemSetup> Setup;
- TActorSystem ActorSystem;
-
- TState State;
-
- TTestCtx(size_t maxThreadCount, size_t sendingMessageCount)
- : MaxThreadCount(maxThreadCount)
- , SendingMessageCount(sendingMessageCount)
- , ExecutorPool(new TBasicExecutorPool(0, MaxThreadCount, 50))
- , Setup(GetActorSystemSetup(ExecutorPool.get()))
- , ActorSystem(Setup)
- {
- }
-
- TTestCtx(size_t maxThreadCount, size_t sendingMessageCount, const TState &state)
- : MaxThreadCount(maxThreadCount)
- , SendingMessageCount(sendingMessageCount)
- , ExecutorPool(new TBasicExecutorPool(0, MaxThreadCount, 50))
- , Setup(GetActorSystemSetup(ExecutorPool.get()))
- , ActorSystem(Setup)
- , State(state)
- {
- }
-
- ~TTestCtx() {
- ExecutorPool.release();
- }
-
- TTestActors RegisterCheckActors(size_t actorCount) {
- TTestActors res(actorCount);
- for (size_t i = 0; i < actorCount; ++i) {
- res.Actors[i] = new TTestSenderActor([&] {
- State.ActorDo();
- });
- res.ActorIds[i] = ActorSystem.Register(res.Actors[i]);
- }
- return res;
- }
- };
-
- struct TCheckingInFlightState {
- TAtomic ExpectedMaximum = 0;
- TAtomic CurrentInFlight = 0;
-
- void ActorStartProcessing() {
- ui32 inFlight = AtomicIncrement(CurrentInFlight);
- ui32 maximum = AtomicGet(ExpectedMaximum);
- if (maximum) {
- UNIT_ASSERT_C(inFlight <= maximum, "inFlight# " << inFlight << " maximum# " << maximum);
- }
- }
-
- void ActorStopProcessing() {
- AtomicDecrement(CurrentInFlight);
- }
-
- void ActorDo() {
- ActorStartProcessing();
- NanoSleep(1'000'000);
- ActorStopProcessing();
- }
- };
-
- Y_UNIT_TEST(DecreaseIncreaseThreadCount) {
- const size_t msgCount = 1e2;
- const size_t size = 4;
- const size_t testCount = 2;
- TTestCtx<TCheckingInFlightState> ctx(size, msgCount);
- ctx.ActorSystem.Start();
-
- TVector<TExecutorThreadStats> statsCopy[testCount];
-
- TTestActors testActors = ctx.RegisterCheckActors(size);
-
- const size_t N = 6;
- const size_t threadsCounts[N] = { 1, 3, 2, 3, 1, 4 };
- for (ui32 idx = 0; idx < 4 * N; ++idx) {
- size_t currentThreadCount = threadsCounts[idx % N];
- ctx.ExecutorPool->SetThreadCount(currentThreadCount);
- AtomicSet(ctx.State.ExpectedMaximum, currentThreadCount);
-
- for (size_t testIdx = 0; testIdx < testCount; ++testIdx) {
- testActors.Start(ctx.ActorSystem, msgCount);
- Sleep(TDuration::MilliSeconds(100));
- testActors.Stop();
- }
- Sleep(TDuration::MilliSeconds(10));
- }
- ctx.ActorSystem.Stop();
- }
-
- Y_UNIT_TEST(ContiniousChangingThreadCount) {
- const size_t msgCount = 1e2;
- const size_t size = 4;
-
- auto begin = TInstant::Now();
- TTestCtx<TCheckingInFlightState> ctx(size, msgCount, TCheckingInFlightState{msgCount});
- ctx.ActorSystem.Start();
- TTestActors testActors = ctx.RegisterCheckActors(size);
-
- testActors.Start(ctx.ActorSystem, msgCount);
-
- const size_t N = 6;
- const size_t threadsCouns[N] = { 1, 3, 2, 3, 1, 4 };
-
- ui64 counter = 0;
-
- TTestSenderActor* changerActor = new TTestSenderActor([&]{
- ctx.State.ActorStartProcessing();
- AtomicSet(ctx.State.ExpectedMaximum, 0);
- ctx.ExecutorPool->SetThreadCount(threadsCouns[counter]);
- NanoSleep(10'000'000);
- AtomicSet(ctx.State.ExpectedMaximum, threadsCouns[counter]);
- counter++;
- if (counter == N) {
- counter = 0;
- }
- ctx.State.ActorStopProcessing();
- });
- TActorId changerActorId = ctx.ActorSystem.Register(changerActor);
- changerActor->Start(changerActorId, msgCount);
- ctx.ActorSystem.Send(changerActorId, new TEvMsg());
-
- while (true) {
- size_t maxCounter = 0;
- for (size_t i = 0; i < size; ++i) {
- maxCounter = Max(maxCounter, testActors.Actors[i]->GetCounter());
- }
- if (maxCounter == 0) {
- break;
- }
- auto now = TInstant::Now();
- UNIT_ASSERT_C(now - begin < TDuration::Seconds(5), "Max counter is " << maxCounter);
- Sleep(TDuration::MilliSeconds(1));
- }
-
- changerActor->Stop();
- ctx.ActorSystem.Stop();
- }
-}
diff --git a/library/cpp/actors/core/executor_pool_io.cpp b/library/cpp/actors/core/executor_pool_io.cpp
deleted file mode 100644
index 78e1d8e1ea..0000000000
--- a/library/cpp/actors/core/executor_pool_io.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-#include "executor_pool_io.h"
-#include "actor.h"
-#include "mailbox.h"
-#include <library/cpp/actors/util/affinity.h>
-#include <library/cpp/actors/util/datetime.h>
-
-namespace NActors {
- TIOExecutorPool::TIOExecutorPool(ui32 poolId, ui32 threads, const TString& poolName, TAffinity* affinity)
- : TExecutorPoolBase(poolId, threads, affinity)
- , Threads(new TThreadCtx[threads])
- , PoolName(poolName)
- {}
-
- TIOExecutorPool::TIOExecutorPool(const TIOExecutorPoolConfig& cfg)
- : TIOExecutorPool(
- cfg.PoolId,
- cfg.Threads,
- cfg.PoolName,
- new TAffinity(cfg.Affinity)
- )
- {}
-
- TIOExecutorPool::~TIOExecutorPool() {
- Threads.Destroy();
- while (ThreadQueue.Pop(0))
- ;
- }
-
- ui32 TIOExecutorPool::GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) {
- i16 workerId = wctx.WorkerId;
- Y_DEBUG_ABORT_UNLESS(workerId < PoolThreads);
-
- NHPTimer::STime elapsed = 0;
- NHPTimer::STime parked = 0;
- NHPTimer::STime hpstart = GetCycleCountFast();
- NHPTimer::STime hpnow;
-
- const TAtomic x = AtomicDecrement(Semaphore);
- if (x < 0) {
- TThreadCtx& threadCtx = Threads[workerId];
- ThreadQueue.Push(workerId + 1, revolvingCounter);
- hpnow = GetCycleCountFast();
- elapsed += hpnow - hpstart;
- if (threadCtx.Pad.Park())
- return 0;
- hpstart = GetCycleCountFast();
- parked += hpstart - hpnow;
- }
-
- while (!RelaxedLoad(&StopFlag)) {
- if (const ui32 activation = Activations.Pop(++revolvingCounter)) {
- hpnow = GetCycleCountFast();
- elapsed += hpnow - hpstart;
- wctx.AddElapsedCycles(ActorSystemIndex, elapsed);
- if (parked > 0) {
- wctx.AddParkedCycles(parked);
- }
- return activation;
- }
- SpinLockPause();
- }
-
- return 0;
- }
-
- void TIOExecutorPool::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) {
- Schedule(deadline - ActorSystem->Timestamp(), ev, cookie, workerId);
- }
-
- void TIOExecutorPool::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) {
- Y_UNUSED(workerId);
-
- const auto current = ActorSystem->Monotonic();
- if (deadline < current)
- deadline = current;
-
- TTicketLock::TGuard guard(&ScheduleLock);
- ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie);
- }
-
- void TIOExecutorPool::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) {
- Y_UNUSED(workerId);
- const auto deadline = ActorSystem->Monotonic() + delta;
-
- TTicketLock::TGuard guard(&ScheduleLock);
- ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie);
- }
-
- void TIOExecutorPool::ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) {
- Activations.Push(activation, revolvingWriteCounter);
- const TAtomic x = AtomicIncrement(Semaphore);
- if (x <= 0) {
- for (;; ++revolvingWriteCounter) {
- if (const ui32 x = ThreadQueue.Pop(revolvingWriteCounter)) {
- const ui32 threadIdx = x - 1;
- Threads[threadIdx].Pad.Unpark();
- return;
- }
- SpinLockPause();
- }
- }
- }
-
- void TIOExecutorPool::Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) {
- TAffinityGuard affinityGuard(Affinity());
-
- ActorSystem = actorSystem;
-
- ScheduleQueue.Reset(new NSchedulerQueue::TQueueType());
-
- for (i16 i = 0; i != PoolThreads; ++i) {
- Threads[i].Thread.Reset(new TExecutorThread(i, 0, actorSystem, this, MailboxTable.Get(), PoolName));
- }
-
- *scheduleReaders = &ScheduleQueue->Reader;
- *scheduleSz = 1;
- }
-
- void TIOExecutorPool::Start() {
- TAffinityGuard affinityGuard(Affinity());
-
- for (i16 i = 0; i != PoolThreads; ++i)
- Threads[i].Thread->Start();
- }
-
- void TIOExecutorPool::PrepareStop() {
- AtomicStore(&StopFlag, true);
- for (i16 i = 0; i != PoolThreads; ++i) {
- Threads[i].Thread->StopFlag = true;
- Threads[i].Pad.Interrupt();
- }
- }
-
- void TIOExecutorPool::Shutdown() {
- for (i16 i = 0; i != PoolThreads; ++i)
- Threads[i].Thread->Join();
- }
-
- void TIOExecutorPool::GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const {
- poolStats.CurrentThreadCount = PoolThreads;
- poolStats.DefaultThreadCount = PoolThreads;
- poolStats.MaxThreadCount = PoolThreads;
- poolStats.PotentialMaxThreadCount = PoolThreads;
- statsCopy.resize(PoolThreads + 1);
- // Save counters from the pool object
- statsCopy[0] = TExecutorThreadStats();
- statsCopy[0].Aggregate(Stats);
- // Per-thread stats
- for (i16 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
deleted file mode 100644
index f3f1a11819..0000000000
--- a/library/cpp/actors/core/executor_pool_io.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-#include "actorsystem.h"
-#include "executor_thread.h"
-#include "scheduler_queue.h"
-#include "executor_pool_base.h"
-#include <library/cpp/actors/actor_type/indexes.h>
-#include <library/cpp/actors/util/ticket_lock.h>
-#include <library/cpp/actors/util/unordered_cache.h>
-#include <library/cpp/actors/util/threadparkpad.h>
-#include <util/system/condvar.h>
-
-namespace NActors {
- class TIOExecutorPool: public TExecutorPoolBase {
- struct TThreadCtx {
- TAutoPtr<TExecutorThread> Thread;
- TThreadParkPad Pad;
- };
-
- TArrayHolder<TThreadCtx> Threads;
- TUnorderedCache<ui32, 512, 4> ThreadQueue;
-
- THolder<NSchedulerQueue::TQueueType> ScheduleQueue;
- TTicketLock ScheduleLock;
-
- const TString PoolName;
- const ui32 ActorSystemIndex = NActors::TActorTypeOperator::GetActorSystemIndex();
- public:
- TIOExecutorPool(ui32 poolId, ui32 threads, const TString& poolName = "", TAffinity* affinity = nullptr);
- explicit TIOExecutorPool(const TIOExecutorPoolConfig& cfg);
- ~TIOExecutorPool();
-
- ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) override;
-
- void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override;
- void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override;
- void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override;
-
- void ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) override;
-
- void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) override;
- void Start() override;
- void PrepareStop() override;
- void Shutdown() override;
-
- void GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const override;
- TString GetName() const override;
- };
-}
diff --git a/library/cpp/actors/core/executor_pool_united.cpp b/library/cpp/actors/core/executor_pool_united.cpp
deleted file mode 100644
index 960545ffb5..0000000000
--- a/library/cpp/actors/core/executor_pool_united.cpp
+++ /dev/null
@@ -1,1455 +0,0 @@
-#include "executor_pool_united.h"
-#include "executor_pool_united_workers.h"
-
-#include "actor.h"
-#include "balancer.h"
-#include "cpu_state.h"
-#include "executor_thread.h"
-#include "probes.h"
-#include "mailbox.h"
-#include "scheduler_queue.h"
-#include <library/cpp/actors/util/affinity.h>
-#include <library/cpp/actors/util/cpu_load_log.h>
-#include <library/cpp/actors/util/datetime.h>
-#include <library/cpp/actors/util/futex.h>
-#include <library/cpp/actors/util/intrinsics.h>
-#include <library/cpp/actors/util/timerfd.h>
-
-#include <util/system/datetime.h>
-#include <util/system/hp_timer.h>
-
-#include <algorithm>
-
-namespace NActors {
- LWTRACE_USING(ACTORLIB_PROVIDER);
-
- struct TUnitedWorkers::TWorker: public TNonCopyable {
- TAutoPtr<TExecutorThread> Thread;
- volatile TThreadId ThreadId = UnknownThreadId;
- NSchedulerQueue::TQueueType SchedulerQueue;
- };
-
- struct TUnitedWorkers::TPool: public TNonCopyable {
- TAtomic Waiters = 0; // Number of idle cpus, waiting for activations in this pool
- char Padding[64 - sizeof(TAtomic)];
-
- TUnorderedCache<ui32, 512, 4> Activations; // MPMC-queue for mailbox activations
- TAtomic Active = 0; // Number of mailboxes ready for execution or currently executing
- TAtomic Tokens = 0; // Pending tokens (token is required for worker to start execution, guarantees concurrency limit and activation availability)
- volatile bool StopFlag = false;
-
- // Configuration
- TPoolId PoolId;
- TAtomicBase Concurrency; // Max concurrent workers running this pool
- IExecutorPool* ExecutorPool;
- TMailboxTable* MailboxTable;
- ui64 TimePerMailboxTs;
- ui32 EventsPerMailbox;
-
- // Cpus this pool is allowed to run on
- // Cpus are specified in wake order
- TStackVec<TCpu*, 15> WakeOrderCpus;
-
- ~TPool() {
- while (Activations.Pop(0)) {}
- }
-
- void Stop() {
- AtomicStore(&StopFlag, true);
- }
-
- bool IsUnited() const {
- return WakeOrderCpus.size();
- }
-
- // Add activation of newly scheduled mailbox. Returns generated token (unless concurrency is exceeded)
- bool PushActivation(ui32 activation, ui64 revolvingCounter) {
- Activations.Push(activation, revolvingCounter);
- TAtomicBase active = AtomicIncrement(Active);
- if (active <= Concurrency) { // token generated
- AtomicIncrement(Tokens);
- return true;
- }
- return false;
- }
-
- template <bool Relaxed>
- static bool TryAcquireTokenImpl(TAtomic* tokens) {
- while (true) {
- TAtomicBase value;
- if constexpr (Relaxed) {
- value = RelaxedLoad(tokens);
- } else {
- value = AtomicLoad(tokens);
- }
- if (value > 0) {
- if (AtomicCas(tokens, value - 1, value)) {
- return true; // token acquired
- }
- } else {
- return false; // no more tokens
- }
- }
- }
-
- // Try acquire pending token. Must be done before execution
- bool TryAcquireToken() {
- return TryAcquireTokenImpl<false>(&Tokens);
- }
-
- // Try acquire pending token. Must be done before execution
- bool TryAcquireTokenRelaxed() {
- return TryAcquireTokenImpl<true>(&Tokens);
- }
-
- // Get activation. Requires acquired token.
- void BeginExecution(ui32& activation, ui64 revolvingCounter) {
- while (!RelaxedLoad(&StopFlag)) {
- if (activation = Activations.Pop(++revolvingCounter)) {
- return;
- }
- SpinLockPause();
- }
- activation = 0; // should stop
- }
-
- // End currently active execution and start new one if token is available.
- // Reuses token if it's not destroyed.
- // Returned `true` means successful switch, `activation` is filled.
- // Returned `false` means execution has ended, no need to call StopExecution()
- bool NextExecution(ui32& activation, ui64 revolvingCounter) {
- if (AtomicDecrement(Active) >= Concurrency) { // reuse just released token
- BeginExecution(activation, revolvingCounter);
- return true;
- } else if (TryAcquireToken()) { // another token acquired
- BeginExecution(activation, revolvingCounter);
- return true;
- }
- return false; // no more tokens available
- }
-
- // Stop active execution. Returns released token (unless it is destroyed)
- bool StopExecution() {
- TAtomicBase active = AtomicDecrement(Active);
- if (active >= Concurrency) { // token released
- AtomicIncrement(Tokens);
- return true;
- }
- return false; // token destroyed
- }
-
- // Switch worker context into this pool
- void Switch(TWorkerContext& wctx, ui64 softDeadlineTs, TExecutorThreadStats& stats) {
- wctx.Switch(ExecutorPool, MailboxTable, TimePerMailboxTs, EventsPerMailbox, softDeadlineTs, &stats);
- }
- };
-
- class TPoolScheduler {
- class TSchedulable {
- // Lower PoolBits store PoolId
- // All other higher bits store virtual runtime in cycles
- using TValue = ui64;
- TValue Value;
-
- static constexpr ui64 PoolIdMask = ui64((1ull << PoolBits) - 1);
- static constexpr ui64 VRunTsMask = ~PoolIdMask;
-
- public:
- explicit TSchedulable(TPoolId poolId = MaxPools, ui64 vrunts = 0)
- : Value((poolId & PoolIdMask) | (vrunts & VRunTsMask))
- {}
-
- TPoolId GetPoolId() const {
- return Value & PoolIdMask;
- }
-
- ui64 GetVRunTs() const {
- // Do not truncate pool id
- // NOTE: it decrease accuracy, but improves performance
- return Value;
- }
-
- ui64 GetPreciseVRunTs() const {
- return Value & VRunTsMask;
- }
-
- void SetVRunTs(ui64 vrunts) {
- Value = (Value & PoolIdMask) | (vrunts & VRunTsMask);
- }
-
- void Account(ui64 base, ui64 ts) {
- // Add at least minimum amount to change Value
- SetVRunTs(base + Max(ts, PoolIdMask + 1));
- }
- };
-
- // For min-heap of Items
- struct TCmp {
- bool operator()(TSchedulable lhs, TSchedulable rhs) const {
- return lhs.GetVRunTs() > rhs.GetVRunTs();
- }
- };
-
- TPoolId Size = 0; // total number of pools on this cpu
- TPoolId Current = 0; // index of current pool in `Items`
-
- // At the beginning `Current` items are orginized as binary min-heap -- ready to be scheduled
- // The rest `Size - Current` items are unordered (required to keep track of last vrunts)
- TSchedulable Items[MaxPools]; // virtual runtime in cycles for each pool
- ui64 MinVRunTs = 0; // virtual runtime used by waking pools (system's vrunts)
- ui64 Ts = 0; // real timestamp of current execution start (for accounting)
-
- // Maps PoolId into it's inverse weight
- ui64 InvWeights[MaxPools];
- static constexpr ui64 VRunTsOverflow = ui64(1ull << 62ull) / MaxPoolWeight;
-
- public:
- void AddPool(TPoolId pool, TPoolWeight weight) {
- Items[Size] = TSchedulable(pool, MinVRunTs);
- Size++;
- InvWeights[pool] = MaxPoolWeight / std::clamp(weight ? weight : DefPoolWeight, MinPoolWeight, MaxPoolWeight);
- }
-
- // Iterate over pools in scheduling order
- // should be used in construction:
- // for (TPoolId pool = Begin(); pool != End(); pool = Next())
- TPoolId Begin() {
- // Wrap vruntime around to avoid overflow, if required
- if (Y_UNLIKELY(MinVRunTs >= VRunTsOverflow)) {
- for (TPoolId i = 0; i < Size; i++) {
- ui64 ts = Items[i].GetPreciseVRunTs();
- Items[i].SetVRunTs(ts >= VRunTsOverflow ? ts - VRunTsOverflow : 0);
- }
- MinVRunTs -= VRunTsOverflow;
- }
- Current = Size;
- std::make_heap(Items, Items + Current, TCmp());
- return Next();
- }
-
- constexpr TPoolId End() const {
- return MaxPools;
- }
-
- TPoolId Next() {
- if (Current > 0) {
- std::pop_heap(Items, Items + Current, TCmp());
- Current--;
- return CurrentPool();
- } else {
- return End();
- }
- }
-
- // Scheduling was successful, we are going to run CurrentPool()
- void Scheduled() {
- MinVRunTs = Max(MinVRunTs, Items[Current].GetPreciseVRunTs());
- // NOTE: Ts is propagated on Account() to avoid gaps
- }
-
- // Schedule specific pool that woke up cpu after idle
- void ScheduledAfterIdle(TPoolId pool, ui64 ts) {
- if (Y_UNLIKELY(ts < Ts)) { // anomaly: time goes backwards (e.g. rdtsc is reset to zero on cpu reset)
- Ts = ts; // just skip anomalous time slice
- return;
- }
- MinVRunTs += (ts - Ts) * (MaxPoolWeight / DefPoolWeight); // propagate system's vrunts to blur difference between pools
- Ts = ts; // propagate time w/o accounting to any pool
-
- // Set specified pool as current, it requires scan
- for (Current = 0; Current < Size && pool != Items[Current].GetPoolId(); Current++) {}
- Y_ABORT_UNLESS(Current < Size);
- }
-
- // Account currently running pool till now (ts)
- void Account(ui64 ts) {
- // Skip time slice for the first run and when time goes backwards (e.g. rdtsc is reset to zero on cpu reset)
- if (Y_LIKELY(Ts > 0 && Ts <= ts)) {
- TPoolId pool = CurrentPool();
- Y_ABORT_UNLESS(pool < MaxPools);
- Items[Current].Account(MinVRunTs, (ts - Ts) * InvWeights[pool]);
- }
- Ts = ts; // propagate time
- }
-
- TPoolId CurrentPool() const {
- return Items[Current].GetPoolId();
- }
- };
-
- // Cyclic array of timers for idle workers to wait for hard preemption on
- struct TIdleQueue: public TNonCopyable {
- TArrayHolder<TTimerFd> Timers;
- size_t Size;
- TAtomic EnqueueCounter = 0;
- TAtomic DequeueCounter = 0;
-
- explicit TIdleQueue(size_t size)
- : Timers(new TTimerFd[size])
- , Size(size)
- {}
-
- void Stop() {
- for (size_t i = 0; i < Size; i++) {
- Timers[i].Wake();
- }
- }
-
- // Returns timer which new idle-worker should wait for
- TTimerFd* Enqueue() {
- return &Timers[AtomicGetAndIncrement(EnqueueCounter) % Size];
- }
-
- // Returns timer that hard preemption should trigger to wake idle-worker
- TTimerFd* Dequeue() {
- return &Timers[AtomicGetAndIncrement(DequeueCounter) % Size];
- }
- };
-
- // Base class for cpu-local managers that help workers on single cpu to cooperate
- struct TCpuLocalManager: public TThrRefBase {
- TUnitedWorkers* United;
-
- explicit TCpuLocalManager(TUnitedWorkers* united)
- : United(united)
- {}
-
- virtual TWorkerId WorkerCount() const = 0;
- virtual void AddWorker(TWorkerId workerId) = 0;
- virtual void Stop() = 0;
- };
-
- // Represents cpu with single associated worker that is able to execute any pool.
- // It always executes pool assigned by balancer and switch pool only if assigned pool has changed
- struct TAssignedCpu: public TCpuLocalManager {
- bool Started = false;
-
- TAssignedCpu(TUnitedWorkers* united)
- : TCpuLocalManager(united)
- {}
-
- TWorkerId WorkerCount() const override {
- return 1;
- }
-
- void AddWorker(TWorkerId workerId) override {
- Y_UNUSED(workerId);
- }
-
- ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) {
- ui32 activation;
- if (Y_UNLIKELY(!Started)) {
- Started = true;
- } else if (Y_UNLIKELY(United->IsPoolReassigned(wctx))) {
- United->StopExecution(wctx.PoolId); // stop current execution and switch pool if reassigned
- } else if (United->NextExecution(wctx.PoolId, activation, revolvingCounter)) {
- return activation; // another activation from currently executing pool (or 0 if stopped)
- }
-
- // Switch to another pool, it blocks until token is acquired
- if (Y_UNLIKELY(!SwitchPool(wctx))) {
- return 0; // stopped
- }
- United->SwitchPool(wctx, 0);
- United->BeginExecution(wctx.PoolId, activation, revolvingCounter);
- return activation;
- }
-
- void Stop() override {
- }
-
- private:
- // Sets next pool to run, and acquires token, blocks if there are no tokens
- bool SwitchPool(TWorkerContext& wctx) {
- if (Y_UNLIKELY(United->IsStopped())) {
- return false;
- }
-
- // Run balancer (if it's time to)
- United->Balance();
-
- // Select pool to execute
- wctx.PoolId = United->AssignedPool(wctx);
- Y_ABORT_UNLESS(wctx.PoolId != CpuShared);
- if (United->TryAcquireToken(wctx.PoolId)) {
- return true;
- }
-
- // No more work -- wait for activations (spinning, then blocked)
- wctx.PoolId = United->Idle(wctx.PoolId, wctx);
-
- // Wakeup or stop occured
- if (Y_UNLIKELY(wctx.PoolId == CpuStopped)) {
- return false;
- }
- return true; // United->Idle() has already acquired token
- }
- };
-
- // Lock-free data structure that help workers on single cpu to discover their state and do hard preemptions
- struct TSharedCpu: public TCpuLocalManager {
- // Current lease
- volatile TLease::TValue CurrentLease;
- char Padding1[64 - sizeof(TLease)];
-
- // Slow pools
- // the highest bit: 1=wait-for-slow-workers mode 0=else
- // any lower bit (poolId is bit position): 1=pool-is-slow 0=pool-is-fast
- volatile TPoolsMask SlowPoolsMask = 0;
- char Padding2[64 - sizeof(TPoolsMask)];
-
- // Must be accessed under never expiring lease to avoid races
- TPoolScheduler PoolSched;
- TWorkerId FastWorker = MaxWorkers;
- TTimerFd* PreemptionTimer = nullptr;
- ui64 HardPreemptionTs = 0;
- bool Started = false;
-
- TIdleQueue IdleQueue;
-
- struct TConfig {
- const TCpuId CpuId;
- const TWorkerId Workers;
- ui64 SoftLimitTs;
- ui64 HardLimitTs;
- ui64 EventLimitTs;
- ui64 LimitPrecisionTs;
- const int IdleWorkerPriority;
- const int FastWorkerPriority;
- const bool NoRealtime;
- const bool NoAffinity;
- const TCpuAllocation CpuAlloc;
-
- TConfig(const TCpuAllocation& allocation, const TUnitedWorkersConfig& united)
- : CpuId(allocation.CpuId)
- , Workers(allocation.AllowedPools.size() + 1)
- , SoftLimitTs(Us2Ts(united.PoolLimitUs))
- , HardLimitTs(Us2Ts(united.PoolLimitUs + united.EventLimitUs))
- , EventLimitTs(Us2Ts(united.EventLimitUs))
- , LimitPrecisionTs(Us2Ts(united.LimitPrecisionUs))
- , IdleWorkerPriority(std::clamp<ui64>(united.IdleWorkerPriority ? united.IdleWorkerPriority : 20, 1, 99))
- , FastWorkerPriority(std::clamp<ui64>(united.FastWorkerPriority ? united.FastWorkerPriority : 10, 1, IdleWorkerPriority - 1))
- , NoRealtime(united.NoRealtime)
- , NoAffinity(united.NoAffinity)
- , CpuAlloc(allocation)
- {}
- };
-
- TConfig Config;
- TVector<TWorkerId> Workers;
-
- TSharedCpu(const TConfig& cfg, TUnitedWorkers* united)
- : TCpuLocalManager(united)
- , IdleQueue(cfg.Workers)
- , Config(cfg)
- {
- for (const auto& pa : Config.CpuAlloc.AllowedPools) {
- PoolSched.AddPool(pa.PoolId, pa.Weight);
- }
- }
-
- TWorkerId WorkerCount() const override {
- return Config.Workers;
- }
-
- void AddWorker(TWorkerId workerId) override {
- if (Workers.empty()) {
- // Grant lease to the first worker
- AtomicStore(&CurrentLease, TLease(workerId, NeverExpire).Value);
- }
- Workers.push_back(workerId);
- }
-
- ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) {
- ui32 activation;
- if (!wctx.Lease.IsNeverExpiring()) {
- if (wctx.SoftDeadlineTs < GetCycleCountFast()) { // stop if lease has expired or is near to be expired
- United->StopExecution(wctx.PoolId);
- } else if (United->NextExecution(wctx.PoolId, activation, revolvingCounter)) {
- return activation; // another activation from currently executing pool (or 0 if stopped)
- }
- }
-
- // Switch to another pool, it blocks until token is acquired
- if (Y_UNLIKELY(!SwitchPool(wctx))) {
- return 0; // stopped
- }
- United->BeginExecution(wctx.PoolId, activation, revolvingCounter);
- return activation;
- }
-
- void Stop() override {
- IdleQueue.Stop();
- }
-
- private:
- enum EPriority {
- IdlePriority, // highest (real-time, Config.IdleWorkerPriority)
- FastPriority, // normal (real-time, Config.FastWorkerPriority)
- SlowPriority, // lowest (not real-time)
- };
-
- enum EWorkerAction {
- // Fast-worker
- ExecuteFast,
- WaitForSlow,
-
- // Slow-worker
- BecameIdle,
- WakeFast,
-
- // Idle-worker
- BecameFast,
- Standby,
-
- // Common
- Stopped,
- };
-
- // Thread-safe; should be called from worker
- // Blocks for idle-workers; sets lease and next pool to run
- bool SwitchPool(TWorkerContext& wctx) {
- TTimerFd* idleTimer = nullptr;
- while (true) {
- if (DisablePreemptionAndTryExtend(wctx.Lease)) { // if fast-worker
- if (Y_UNLIKELY(!Started)) {
- SetPriority(0, FastPriority);
- Started = true;
- }
- while (true) {
- switch (FastWorkerAction(wctx)) {
- case ExecuteFast:
- United->SwitchPool(wctx, wctx.Lease.GetPreciseExpireTs() - Config.EventLimitTs);
- EnablePreemptionAndGrant(wctx.Lease);
- return true;
- case WaitForSlow:
- FastWorkerSleep(GetCycleCountFast() + Config.SoftLimitTs);
- break;
- case Stopped: return false;
- default: Y_ABORT();
- }
- }
- } else if (wctx.Lease.IsNeverExpiring()) { // if idle-worker
- switch (IdleWorkerAction(idleTimer, wctx.Lease.GetWorkerId())) {
- case BecameFast:
- SetPriority(0, FastPriority);
- break; // try acquire new lease
- case Standby:
- if (!idleTimer) {
- idleTimer = IdleQueue.Enqueue();
- }
- SetPriority(0, IdlePriority);
- idleTimer->Wait();
- break;
- case Stopped: return false;
- default: Y_ABORT();
- }
- } else { // lease has expired and hard preemption occured, so we are executing in a slow-worker
- wctx.IncrementPreemptedEvents();
- switch (SlowWorkerAction(wctx.PoolId)) {
- case WakeFast:
- WakeFastWorker();
- [[fallthrough]]; // no break; pass through
- case BecameIdle:
- wctx.Lease = wctx.Lease.NeverExpire();
- wctx.PoolId = MaxPools;
- idleTimer = nullptr;
- break;
- case Stopped: return false;
- default: Y_ABORT();
- }
- }
- }
- }
-
- enum ETryRunPool {
- RunFastPool,
- RunSlowPool,
- NoTokens,
- };
-
- ETryRunPool TryRun(TPoolId pool) {
- while (true) {
- // updates WaitPoolsFlag in SlowPoolsMask according to scheduled pool slowness
- TPoolsMask slow = AtomicLoad(&SlowPoolsMask);
- if ((1ull << pool) & slow) { // we are about to execute slow pool (fast-worker will just wait, token is NOT required)
- if (slow & WaitPoolsFlag) {
- return RunSlowPool; // wait flag is already set
- } else {
- if (AtomicCas(&SlowPoolsMask, slow | WaitPoolsFlag, slow)) { // try set wait flag
- return RunSlowPool; // wait flag has been successfully set
- }
- }
- } else { // we are about to execute fast pool, token required
- if (slow & WaitPoolsFlag) { // reset wait flag if required
- if (AtomicCas(&SlowPoolsMask, slow & ~WaitPoolsFlag, slow)) { // try reset wait flag
- return United->TryAcquireToken(pool) ? RunFastPool : NoTokens; // wait flag has been successfully reset
- }
- } else {
- return United->TryAcquireToken(pool) ? RunFastPool : NoTokens; // wait flag is already reset
- }
- }
- }
- }
-
- EWorkerAction FastWorkerAction(TWorkerContext& wctx) {
- if (Y_UNLIKELY(United->IsStopped())) {
- return Stopped;
- }
-
- // Account current pool
- ui64 ts = GetCycleCountFast();
- PoolSched.Account(ts);
-
- // Select next pool to execute
- for (wctx.PoolId = PoolSched.Begin(); wctx.PoolId != PoolSched.End(); wctx.PoolId = PoolSched.Next()) {
- switch (TryRun(wctx.PoolId)) {
- case RunFastPool:
- PoolSched.Scheduled();
- wctx.Lease = PostponePreemption(wctx.Lease.GetWorkerId(), ts);
- return ExecuteFast;
- case RunSlowPool:
- PoolSched.Scheduled();
- ResetPreemption(wctx.Lease.GetWorkerId(), ts); // there is no point in preemption during wait
- return WaitForSlow;
- case NoTokens: // concurrency limit reached, or no more work in pool
- break; // just try next pool (if any)
- }
- }
-
- // No more work, no slow-workers -- wait for activations (active, then blocked)
- wctx.PoolId = United->Idle(CpuShared, wctx);
-
- // Wakeup or stop occured
- if (Y_UNLIKELY(wctx.PoolId == CpuStopped)) {
- return Stopped;
- }
- ts = GetCycleCountFast();
- PoolSched.ScheduledAfterIdle(wctx.PoolId, ts);
- wctx.Lease = PostponePreemption(wctx.Lease.GetWorkerId(), ts);
- return ExecuteFast; // United->Idle() has already acquired token
- }
-
- EWorkerAction IdleWorkerAction(TTimerFd* idleTimer, TWorkerId workerId) {
- if (Y_UNLIKELY(United->IsStopped())) {
- return Stopped;
- }
- if (!idleTimer) { // either worker start or became idle -- hard preemption is not required
- return Standby;
- }
-
- TLease lease = TLease(AtomicLoad(&CurrentLease));
- ui64 ts = GetCycleCountFast();
- if (lease.GetExpireTs() < ts) { // current lease has expired
- if (TryBeginHardPreemption(lease)) {
- SetPoolIsSlowFlag(PoolSched.CurrentPool());
- TWorkerId preempted = lease.GetWorkerId();
- SetPriority(United->GetWorkerThreadId(preempted), SlowPriority);
- LWPROBE(HardPreemption, Config.CpuId, PoolSched.CurrentPool(), preempted, workerId);
- EndHardPreemption(workerId);
- return BecameFast;
- } else {
- // Lease has been changed just now, no way we need preemption right now, so no retry needed
- return Standby;
- }
- } else {
- // Lease has not expired yet (maybe never expiring lease)
- return Standby;
- }
- }
-
- EWorkerAction SlowWorkerAction(TPoolId pool) {
- if (Y_UNLIKELY(United->IsStopped())) {
- return Stopped;
- }
- while (true) {
- TPoolsMask slow = AtomicLoad(&SlowPoolsMask);
- if (slow & (1ull << pool)) {
- if (slow == (1ull << pool) & WaitPoolsFlag) { // the last slow pool is going to became fast
- if (AtomicCas(&SlowPoolsMask, 0, slow)) { // reset both pool-is-slow flag and WaitPoolsFlag
- return WakeFast;
- }
- } else { // there are (a) several slow-worker or (b) one slow-worker w/o waiting fast-worker
- if (AtomicCas(&SlowPoolsMask, slow & ~(1ull << pool), slow)) { // reset pool-is-slow flag
- return BecameIdle;
- }
- }
- } else {
- // SlowWorkerAction has been called between TryBeginHardPreemption and SetPoolIsSlowFlag
- // flag for this pool is not set yet, but we can be sure pool is slow:
- // - because SlowWorkerAction has been called;
- // - this mean lease has expired and hard preemption occured.
- // So just wait other worker to call SetPoolIsSlowFlag
- LWPROBE(SlowWorkerActionRace, Config.CpuId, pool, slow);
- }
- }
- }
-
- void SetPoolIsSlowFlag(TPoolId pool) {
- while (true) {
- TPoolsMask slow = AtomicLoad(&SlowPoolsMask);
- if ((slow & (1ull << pool)) == 0) { // if pool is fast
- if (AtomicCas(&SlowPoolsMask, slow | (1ull << pool), slow)) { // set pool-is-slow flag
- return;
- }
- } else {
- Y_ABORT("two slow-workers executing the same pool on the same core");
- return; // pool is already slow
- }
- }
- }
-
- bool TryBeginHardPreemption(TLease lease) {
- return AtomicCas(&CurrentLease, HardPreemptionLease, lease);
- }
-
- void EndHardPreemption(TWorkerId to) {
- ATOMIC_COMPILER_BARRIER();
- if (!AtomicCas(&CurrentLease, TLease(to, NeverExpire), HardPreemptionLease)) {
- Y_ABORT("hard preemption failed");
- }
- }
-
- bool DisablePreemptionAndTryExtend(TLease lease) {
- return AtomicCas(&CurrentLease, lease.NeverExpire(), lease);
- }
-
- void EnablePreemptionAndGrant(TLease lease) {
- ATOMIC_COMPILER_BARRIER();
- if (!AtomicCas(&CurrentLease, lease, lease.NeverExpire())) {
- Y_ABORT("lease grant failed");
- }
- }
-
- void FastWorkerSleep(ui64 deadlineTs) {
- while (true) {
- TPoolsMask slow = AtomicLoad(&SlowPoolsMask);
- if ((slow & WaitPoolsFlag) == 0) {
- return; // woken by WakeFast action
- }
- ui64 ts = GetCycleCountFast();
- if (deadlineTs <= ts) {
- if (AtomicCas(&SlowPoolsMask, slow & ~WaitPoolsFlag, slow)) { // try reset wait flag
- return; // wait flag has been successfully reset after timeout
- }
- } else { // should wait
- ui64 timeoutNs = Ts2Ns(deadlineTs - ts);
-#ifdef _linux_
- timespec timeout;
- timeout.tv_sec = timeoutNs / 1'000'000'000;
- timeout.tv_nsec = timeoutNs % 1'000'000'000;
- SysFutex(FastWorkerFutex(), FUTEX_WAIT_PRIVATE, FastWorkerFutexValue(slow), &timeout, nullptr, 0);
-#else
- NanoSleep(timeoutNs); // non-linux wake is not supported, cpu will go idle on slow -> fast switch
-#endif
- }
- }
- }
-
- void WakeFastWorker() {
-#ifdef _linux_
- SysFutex(FastWorkerFutex(), FUTEX_WAKE_PRIVATE, 1, nullptr, nullptr, 0);
-#endif
- }
-
-#ifdef _linux_
- ui32* FastWorkerFutex() {
- // Actually we wait on one highest bit, but futex value size is 4 bytes on all platforms
- static_assert(sizeof(TPoolsMask) >= 4, "cannot be used as futex value on linux");
- return (ui32*)&SlowPoolsMask + 1; // higher 32 bits (little endian assumed)
- }
-
- ui32 FastWorkerFutexValue(TPoolsMask slow) {
- return ui32(slow >> 32); // higher 32 bits
- }
-#endif
-
- void SetPriority(TThreadId tid, EPriority priority) {
- if (Config.NoRealtime) {
- return;
- }
-#ifdef _linux_
- int policy;
- struct sched_param param;
- switch (priority) {
- case IdlePriority:
- policy = SCHED_FIFO;
- param.sched_priority = Config.IdleWorkerPriority;
- break;
- case FastPriority:
- policy = SCHED_FIFO;
- param.sched_priority = Config.FastWorkerPriority;
- break;
- case SlowPriority:
- policy = SCHED_OTHER;
- param.sched_priority = 0;
- break;
- }
- int ret = sched_setscheduler(tid, policy, &param);
- switch (ret) {
- case 0: return;
- case EINVAL:
- Y_ABORT("sched_setscheduler(%" PRIu64 ", %d, %d) -> EINVAL", tid, policy, param.sched_priority);
- case EPERM:
- // Requirements:
- // * CAP_SYS_NICE capability to run real-time processes and set cpu affinity.
- // Either run under root or set application capabilities:
- // sudo setcap cap_sys_nice=eip BINARY
- // * Non-zero rt-runtime (in case cgroups are used).
- // Either (a) disable global limit on RT processes bandwidth:
- // sudo sysctl -w kernel.sched_rt_runtime_us=-1
- // Or (b) set non-zero rt-runtime for your cgroup:
- // echo -1 > /sys/fs/cgroup/cpu/[cgroup]/cpu.rt_runtime_us
- // (also set the same value for every parent cgroup)
- // https://www.kernel.org/doc/Documentation/scheduler/sched-rt-group.txt
- Y_ABORT("sched_setscheduler(%" PRIu64 ", %d, %d) -> EPERM", tid, policy, param.sched_priority);
- case ESRCH:
- Y_ABORT("sched_setscheduler(%" PRIu64 ", %d, %d) -> ESRCH", tid, policy, param.sched_priority);
- default:
- Y_ABORT("sched_setscheduler(%" PRIu64 ", %d, %d) -> %d", tid, policy, param.sched_priority, ret);
- }
-#else
- Y_UNUSED(tid);
- Y_UNUSED(priority);
-#endif
- }
-
- void ResetPreemption(TWorkerId fastWorkerId, ui64 ts) {
- if (Y_UNLIKELY(!PreemptionTimer)) {
- return;
- }
- if (FastWorker == fastWorkerId && HardPreemptionTs > 0) {
- PreemptionTimer->Reset();
- LWPROBE(ResetPreemptionTimer, Config.CpuId, FastWorker, PreemptionTimer->Fd, Ts2Ms(ts), Ts2Ms(HardPreemptionTs));
- HardPreemptionTs = 0;
- }
- }
-
- TLease PostponePreemption(TWorkerId fastWorkerId, ui64 ts) {
- // Select new timer after hard preemption
- if (FastWorker != fastWorkerId) {
- FastWorker = fastWorkerId;
- PreemptionTimer = IdleQueue.Dequeue();
- HardPreemptionTs = 0;
- }
-
- ui64 hardPreemptionTs = ts + Config.HardLimitTs;
- if (hardPreemptionTs > HardPreemptionTs) {
- // Reset timer (at most once in TickIntervalTs, sacrifice precision)
- HardPreemptionTs = hardPreemptionTs + Config.LimitPrecisionTs;
- PreemptionTimer->Set(HardPreemptionTs);
- LWPROBE(SetPreemptionTimer, Config.CpuId, FastWorker, PreemptionTimer->Fd, Ts2Ms(ts), Ts2Ms(HardPreemptionTs));
- }
-
- return TLease(fastWorkerId, hardPreemptionTs);
- }
- };
-
- // Proxy for start and switching TUnitedExecutorPool-s on single cpu via GetReadyActivation()
- // (does not implement any other method in IExecutorPool)
- class TCpuExecutorPool: public IExecutorPool {
- const TString Name;
-
- public:
- explicit TCpuExecutorPool(const TString& name)
- : IExecutorPool(MaxPools)
- , Name(name)
- {}
-
- TString GetName() const override {
- return Name;
- }
-
- void SetRealTimeMode() const override {
- // derived classes controls rt-priority - do nothing
- }
-
- // Should never be called
- void ReclaimMailbox(TMailboxType::EType, ui32, TWorkerId, ui64) override { Y_ABORT(); }
- TMailboxHeader *ResolveMailbox(ui32) override { Y_ABORT(); }
- void Schedule(TInstant, TAutoPtr<IEventHandle>, ISchedulerCookie*, TWorkerId) override { Y_ABORT(); }
- void Schedule(TMonotonic, TAutoPtr<IEventHandle>, ISchedulerCookie*, TWorkerId) override { Y_ABORT(); }
- void Schedule(TDuration, TAutoPtr<IEventHandle>, ISchedulerCookie*, TWorkerId) override { Y_ABORT(); }
- bool Send(TAutoPtr<IEventHandle>&) override { Y_ABORT(); }
- bool SpecificSend(TAutoPtr<IEventHandle>&) override { Y_ABORT(); }
- void ScheduleActivation(ui32) override { Y_ABORT(); }
- void SpecificScheduleActivation(ui32) override { Y_ABORT(); }
- void ScheduleActivationEx(ui32, ui64) override { Y_ABORT(); }
- TActorId Register(IActor*, TMailboxType::EType, ui64, const TActorId&) override { Y_ABORT(); }
- TActorId Register(IActor*, TMailboxHeader*, ui32, const TActorId&) override { Y_ABORT(); }
- void Prepare(TActorSystem*, NSchedulerQueue::TReader**, ui32*) override { Y_ABORT(); }
- void Start() override { Y_ABORT(); }
- void PrepareStop() override { Y_ABORT(); }
- void Shutdown() override { Y_ABORT(); }
- bool Cleanup() override { Y_ABORT(); }
- };
-
- // Proxy executor pool working with cpu-local scheduler (aka actorsystem 2.0)
- class TSharedCpuExecutorPool: public TCpuExecutorPool {
- TSharedCpu* Local;
- TIntrusivePtr<TAffinity> SingleCpuAffinity; // no migration support yet
- public:
- explicit TSharedCpuExecutorPool(TSharedCpu* local, const TUnitedWorkersConfig& config)
- : TCpuExecutorPool("u-" + ToString(local->Config.CpuId))
- , Local(local)
- , SingleCpuAffinity(config.NoAffinity ? nullptr : new TAffinity(TCpuMask(local->Config.CpuId)))
- {}
-
- TAffinity* Affinity() const override {
- return SingleCpuAffinity.Get();
- }
-
- ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) override {
- return Local->GetReadyActivation(wctx, revolvingCounter);
- }
- };
-
- // Proxy executor pool working with balancer and assigned pools (aka actorsystem 1.5)
- class TAssignedCpuExecutorPool: public TCpuExecutorPool {
- TAssignedCpu* Local;
- TIntrusivePtr<TAffinity> CpuAffinity;
- public:
- explicit TAssignedCpuExecutorPool(TAssignedCpu* local, const TUnitedWorkersConfig& config)
- : TCpuExecutorPool("United")
- , Local(local)
- , CpuAffinity(config.NoAffinity ? nullptr : new TAffinity(config.Allowed))
- {}
-
- TAffinity* Affinity() const override {
- return CpuAffinity.Get();
- }
-
- ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) override {
- return Local->GetReadyActivation(wctx, revolvingCounter);
- }
- };
-
- // Representation of a single cpu and it's state visible to other cpus and pools
- struct TUnitedWorkers::TCpu: public TNonCopyable {
- struct TScopedWaiters {
- TCpu& Cpu;
- TPool* AssignedPool; // nullptr if CpuShared
-
- // Subscribe on wakeups from allowed pools
- TScopedWaiters(TCpu& cpu, TPool* assignedPool) : Cpu(cpu), AssignedPool(assignedPool) {
- if (!AssignedPool) {
- for (TPool* pool : Cpu.AllowedPools) {
- AtomicIncrement(pool->Waiters);
- }
- } else {
- AtomicIncrement(AssignedPool->Waiters);
- }
- }
-
- // Unsubscribe from pools we've subscribed on
- ~TScopedWaiters() {
- if (!AssignedPool) {
- for (TPool* pool : Cpu.AllowedPools) {
- AtomicDecrement(pool->Waiters);
- }
- } else {
- AtomicDecrement(AssignedPool->Waiters);
- }
- }
- };
-
- // Current cpu state important for other cpus and balancer
- TCpuState State;
-
- // Thread-safe per pool stats
- // NOTE: It's guaranteed that cpu never executes two instance of the same pool
- TVector<TExecutorThreadStats> PoolStats;
- TCpuLoadLog<1024> LoadLog;
-
-
- // Configuration
- TCpuId CpuId;
- THolder<TCpuLocalManager> LocalManager;
- THolder<TCpuExecutorPool> ExecutorPool;
-
- // Pools allowed to run on this cpu
- TStackVec<TPool*, 15> AllowedPools;
-
- void Stop() {
- if (LocalManager) {
- State.Stop();
- LocalManager->Stop();
- }
- }
-
- bool StartSpinning(TUnitedWorkers* united, TPool* assignedPool, TPoolId& result) {
- // Mark cpu as idle
- if (Y_UNLIKELY(!State.StartSpinning())) {
- result = CpuStopped;
- return true;
- }
-
- // Avoid using multiple atomic seq_cst loads in cycle, use barrier once and relaxed ops
- AtomicBarrier();
-
- // Check there is no pending tokens (can be released before Waiters increment)
- if (!assignedPool) {
- for (TPool* pool : AllowedPools) {
- if (pool->TryAcquireTokenRelaxed()) {
- result = WakeWithTokenAcquired(united, pool->PoolId);
- return true; // token acquired or stop
- }
- }
- } else {
- if (assignedPool->TryAcquireTokenRelaxed()) {
- result = WakeWithTokenAcquired(united, assignedPool->PoolId);
- return true; // token acquired or stop
- }
- }
-
- // At this point we can be sure wakeup won't be lost
- // So we can actively spin or block w/o checking for pending tokens
- return false;
- }
-
- bool ActiveWait(ui64 spinThresholdTs, TPoolId& result) {
- ui64 ts = GetCycleCountFast();
- LoadLog.RegisterBusyPeriod(ts);
- ui64 deadline = ts + spinThresholdTs;
- while (GetCycleCountFast() < deadline) {
- for (ui32 i = 0; i < 12; ++i) {
- TPoolId current = State.CurrentPool();
- if (current == CpuSpinning) {
- SpinLockPause();
- } else {
- result = current;
- LoadLog.RegisterIdlePeriod(GetCycleCountFast());
- return true; // wakeup
- }
- }
- }
- return false; // spin threshold exceeded, no wakeups
- }
-
- bool StartBlocking(TPoolId& result) {
- // Switch into blocked state
- if (State.StartBlocking()) {
- result = State.CurrentPool();
- return true;
- } else {
- return false;
- }
- }
-
- bool BlockedWait(TPoolId& result, ui64 timeoutNs) {
- return State.Block(timeoutNs, result);
- }
-
- void SwitchPool(TPoolId pool) {
- return State.SwitchPool(pool);
- }
-
- private:
- TPoolId WakeWithTokenAcquired(TUnitedWorkers* united, TPoolId token) {
- switch (State.WakeWithTokenAcquired(token)) {
- case TCpuState::Woken: // we've got token and successfully woken up this cpu
- // NOTE: sending thread may also wakeup another worker, which wont be able to acquire token and will go idle (it's ok)
- return token;
- case TCpuState::NotIdle: { // wakeup event has also occured
- TPoolId wakeup = State.CurrentPool();
- if (wakeup != token) { // token and wakeup for different pools
- united->TryWake(wakeup); // rewake another cpu to avoid losing wakeup
- }
- return token;
- }
- case TCpuState::Forbidden:
- Y_ABORT();
- case TCpuState::Stopped:
- return CpuStopped;
- }
- }
- };
-
- TUnitedWorkers::TUnitedWorkers(
- const TUnitedWorkersConfig& config,
- const TVector<TUnitedExecutorPoolConfig>& unitedPools,
- const TCpuAllocationConfig& allocation,
- IBalancer* balancer)
- : Balancer(balancer)
- , Config(config)
- , Allocation(allocation)
- {
- // Find max pool id and initialize pools
- PoolCount = 0;
- for (const TCpuAllocation& cpuAlloc : allocation.Items) {
- for (const auto& pa : cpuAlloc.AllowedPools) {
- PoolCount = Max<size_t>(PoolCount, pa.PoolId + 1);
- }
- }
- Pools.Reset(new TPool[PoolCount]);
-
- // Find max cpu id and initialize cpus
- CpuCount = 0;
- for (const TCpuAllocation& cpuAlloc : allocation.Items) {
- CpuCount = Max<size_t>(CpuCount, cpuAlloc.CpuId + 1);
- }
- Cpus.Reset(new TCpu[CpuCount]);
-
- // Setup allocated cpus
- // NOTE: leave gaps for not allocated cpus (default-initialized)
- WorkerCount = 0;
- for (const TCpuAllocation& cpuAlloc : allocation.Items) {
- TCpu& cpu = Cpus[cpuAlloc.CpuId];
- cpu.CpuId = cpuAlloc.CpuId;
- cpu.PoolStats.resize(PoolCount); // NOTE: also may have gaps
- for (const auto& pa : cpuAlloc.AllowedPools) {
- cpu.AllowedPools.emplace_back(&Pools[pa.PoolId]);
- }
-
- // Setup balancing and cpu-local manager
- if (!Balancer->AddCpu(cpuAlloc, &cpu.State)) {
- cpu.State.SwitchPool(0); // set initial state to non-idle to avoid losing wakeups on start
- cpu.State.AssignPool(CpuShared);
- TSharedCpu* local = new TSharedCpu(TSharedCpu::TConfig(cpuAlloc, Config), this);
- cpu.LocalManager.Reset(local);
- cpu.ExecutorPool.Reset(new TSharedCpuExecutorPool(local, Config));
- } else {
- TAssignedCpu* local = new TAssignedCpu(this);
- cpu.LocalManager.Reset(local);
- cpu.ExecutorPool.Reset(new TAssignedCpuExecutorPool(local, Config));
- }
- WorkerCount += cpu.LocalManager->WorkerCount();
- }
-
- // Initialize workers
- Workers.Reset(new TWorker[WorkerCount]);
-
- // Setup pools
- // NOTE: leave gaps for not united pools (default-initialized)
- for (const TUnitedExecutorPoolConfig& cfg : unitedPools) {
- TPool& pool = Pools[cfg.PoolId];
- Y_ABORT_UNLESS(cfg.PoolId < MaxPools);
- pool.PoolId = cfg.PoolId;
- pool.Concurrency = cfg.Concurrency ? cfg.Concurrency : Config.CpuCount;
- pool.ExecutorPool = nullptr; // should be set later using SetupPool()
- pool.MailboxTable = nullptr; // should be set later using SetupPool()
- pool.TimePerMailboxTs = DurationToCycles(cfg.TimePerMailbox);
- pool.EventsPerMailbox = cfg.EventsPerMailbox;
-
- // Reinitialize per cpu pool stats with right MaxActivityType
- for (const TCpuAllocation& cpuAlloc : allocation.Items) {
- TCpu& cpu = Cpus[cpuAlloc.CpuId];
- cpu.PoolStats[cfg.PoolId] = TExecutorThreadStats();
- }
-
- // Setup WakeOrderCpus: left to right exclusive cpus, then left to right shared cpus.
- // Waking exclusive cpus first reduce load on shared cpu and improve latency isolation, which is
- // the point of using exclusive cpu. But note that number of actively spinning idle cpus may increase,
- // so cpu consumption on light load is higher.
- for (const TCpuAllocation& cpuAlloc : allocation.Items) {
- TCpu& cpu = Cpus[cpuAlloc.CpuId];
- if (cpu.AllowedPools.size() == 1 && cpu.AllowedPools[0] == &pool) {
- pool.WakeOrderCpus.emplace_back(&cpu);
- }
- }
- for (const TCpuAllocation& cpuAlloc : allocation.Items) {
- TCpu& cpu = Cpus[cpuAlloc.CpuId];
- if (cpu.AllowedPools.size() > 1 && cpuAlloc.HasPool(pool.PoolId)) {
- pool.WakeOrderCpus.emplace_back(&cpu);
- }
- }
- }
- }
-
- TUnitedWorkers::~TUnitedWorkers() {
- }
-
- void TUnitedWorkers::Prepare(TActorSystem* actorSystem, TVector<NSchedulerQueue::TReader*>& scheduleReaders) {
- // Setup allocated cpus
- // NOTE: leave gaps for not allocated cpus (default-initialized)
- TWorkerId workers = 0;
- for (TCpuId cpuId = 0; cpuId < CpuCount; cpuId++) {
- TCpu& cpu = Cpus[cpuId];
-
- // Setup cpu-local workers
- if (cpu.LocalManager) {
- for (i16 i = 0; i < cpu.LocalManager->WorkerCount(); i++) {
- TWorkerId workerId = workers++;
- cpu.LocalManager->AddWorker(workerId);
-
- // Setup worker
- Y_ABORT_UNLESS(workerId < WorkerCount);
- Workers[workerId].Thread.Reset(new TExecutorThread(
- workerId,
- cpu.CpuId,
- actorSystem,
- cpu.ExecutorPool.Get(), // use cpu-local manager as proxy executor for all workers on cpu
- nullptr, // MailboxTable is pool-specific, will be set on pool switch
- cpu.ExecutorPool->GetName()));
- // NOTE: TWorker::ThreadId will be initialized after in Start()
-
- scheduleReaders.push_back(&Workers[workerId].SchedulerQueue.Reader);
- }
- }
- }
- }
-
- void TUnitedWorkers::Start() {
- for (TWorkerId workerId = 0; workerId < WorkerCount; workerId++) {
- Workers[workerId].Thread->Start();
- }
- for (TWorkerId workerId = 0; workerId < WorkerCount; workerId++) {
- AtomicStore(&Workers[workerId].ThreadId, Workers[workerId].Thread->GetThreadId());
- }
- }
-
- inline TThreadId TUnitedWorkers::GetWorkerThreadId(TWorkerId workerId) const {
- volatile TThreadId* threadId = &Workers[workerId].ThreadId;
-#ifdef _linux_
- while (AtomicLoad(threadId) == UnknownThreadId) {
- NanoSleep(1000);
- }
-#endif
- return AtomicLoad(threadId);
- }
-
- inline NSchedulerQueue::TWriter* TUnitedWorkers::GetScheduleWriter(TWorkerId workerId) const {
- return &Workers[workerId].SchedulerQueue.Writer;
- }
-
- void TUnitedWorkers::SetupPool(TPoolId pool, IExecutorPool* executorPool, TMailboxTable* mailboxTable) {
- Pools[pool].ExecutorPool = executorPool;
- Pools[pool].MailboxTable = mailboxTable;
- }
-
- void TUnitedWorkers::PrepareStop() {
- AtomicStore(&StopFlag, true);
- for (TPoolId pool = 0; pool < PoolCount; pool++) {
- Pools[pool].Stop();
- }
- for (TCpuId cpuId = 0; cpuId < CpuCount; cpuId++) {
- Cpus[cpuId].Stop();
- }
- }
-
- void TUnitedWorkers::Shutdown() {
- for (TWorkerId workerId = 0; workerId < WorkerCount; workerId++) {
- Workers[workerId].Thread->Join();
- }
- }
-
- inline void TUnitedWorkers::PushActivation(TPoolId pool, ui32 activation, ui64 revolvingCounter) {
- if (Pools[pool].PushActivation(activation, revolvingCounter)) { // token generated
- TryWake(pool);
- }
- }
-
- inline bool TUnitedWorkers::TryAcquireToken(TPoolId pool) {
- return Pools[pool].TryAcquireToken();
- }
-
- inline void TUnitedWorkers::TryWake(TPoolId pool) {
- // Avoid using multiple atomic seq_cst loads in cycle, use barrier once
- AtomicBarrier();
-
- // Scan every allowed cpu in pool's wakeup order and try to wake the first idle cpu
- if (RelaxedLoad(&Pools[pool].Waiters) > 0) {
- for (TCpu* cpu : Pools[pool].WakeOrderCpus) {
- if (cpu->State.WakeWithoutToken(pool) == TCpuState::Woken) {
- return; // successful wake up
- }
- }
- }
-
- // Cpu has not been woken up
- }
-
- inline void TUnitedWorkers::BeginExecution(TPoolId pool, ui32& activation, ui64 revolvingCounter) {
- Pools[pool].BeginExecution(activation, revolvingCounter);
- }
-
- inline bool TUnitedWorkers::NextExecution(TPoolId pool, ui32& activation, ui64 revolvingCounter) {
- return Pools[pool].NextExecution(activation, revolvingCounter);
- }
-
- inline void TUnitedWorkers::StopExecution(TPoolId pool) {
- if (Pools[pool].StopExecution()) { // pending token
- TryWake(pool);
- }
- }
-
- inline void TUnitedWorkers::Balance() {
- ui64 ts = GetCycleCountFast();
- if (Balancer->TryLock(ts)) {
- for (TPoolId pool = 0; pool < PoolCount; pool++) {
- if (Pools[pool].IsUnited()) {
- ui64 ElapsedTs = 0;
- ui64 ParkedTs = 0;
- TStackVec<TCpuLoadLog<1024>*, 128> logs;
- ui64 worstActivationTimeUs = 0;
- for (TCpu* cpu : Pools[pool].WakeOrderCpus) {
- TExecutorThreadStats& cpuStats = cpu->PoolStats[pool];
- ElapsedTs += cpuStats.ElapsedTicks;
- ParkedTs += cpuStats.ParkedTicks;
- worstActivationTimeUs = Max(worstActivationTimeUs, cpuStats.WorstActivationTimeUs);
- AtomicStore<decltype(cpuStats.WorstActivationTimeUs)>(&cpuStats.WorstActivationTimeUs, 0ul);
- logs.push_back(&cpu->LoadLog);
- }
- ui64 minPeriodTs = Min(ui64(Us2Ts(Balancer->GetPeriodUs())), ui64((1024ull-2ull)*64ull*128ull*1024ull));
- ui64 estimatedTs = MinusOneCpuEstimator.MaxLatencyIncreaseWithOneLessCpu(
- &logs[0], logs.size(), ts, minPeriodTs);
- TBalancerStats stats;
- stats.Ts = ts;
- stats.CpuUs = Ts2Us(ElapsedTs);
- stats.IdleUs = Ts2Us(ParkedTs);
- stats.ExpectedLatencyIncreaseUs = Ts2Us(estimatedTs);
- stats.WorstActivationTimeUs = worstActivationTimeUs;
- Balancer->SetPoolStats(pool, stats);
- }
- }
- Balancer->Balance();
- Balancer->Unlock();
- }
- }
-
- inline TPoolId TUnitedWorkers::AssignedPool(TWorkerContext& wctx) {
- return Cpus[wctx.CpuId].State.AssignedPool();
- }
-
- inline bool TUnitedWorkers::IsPoolReassigned(TWorkerContext& wctx) {
- return Cpus[wctx.CpuId].State.IsPoolReassigned(wctx.PoolId);
- }
-
- inline void TUnitedWorkers::SwitchPool(TWorkerContext& wctx, ui64 softDeadlineTs) {
- Pools[wctx.PoolId].Switch(wctx, softDeadlineTs, Cpus[wctx.CpuId].PoolStats[wctx.PoolId]);
- Cpus[wctx.CpuId].SwitchPool(wctx.PoolId);
- }
-
- TPoolId TUnitedWorkers::Idle(TPoolId assigned, TWorkerContext& wctx) {
- wctx.SwitchToIdle();
-
- TPoolId result;
- TTimeTracker timeTracker;
- TCpu& cpu = Cpus[wctx.CpuId];
- TPool* assignedPool = assigned == CpuShared ? nullptr : &Pools[assigned];
- TCpu::TScopedWaiters scopedWaiters(cpu, assignedPool);
- while (true) {
- if (cpu.StartSpinning(this, assignedPool, result)) {
- break; // token already acquired (or stop)
- }
- result = WaitSequence(cpu, wctx, timeTracker);
- if (Y_UNLIKELY(result == CpuStopped) || TryAcquireToken(result)) {
- break; // token acquired (or stop)
- }
- }
-
- wctx.AddElapsedCycles(ActorSystemIndex, timeTracker.Elapsed());
- return result;
- }
-
- TPoolId TUnitedWorkers::WaitSequence(TCpu& cpu, TWorkerContext& wctx, TTimeTracker& timeTracker) {
- TPoolId result;
- if (cpu.ActiveWait(Us2Ts(Config.SpinThresholdUs), result)) {
- wctx.AddElapsedCycles(ActorSystemIndex, timeTracker.Elapsed());
- return result;
- }
- if (cpu.StartBlocking(result)) {
- wctx.AddElapsedCycles(ActorSystemIndex, timeTracker.Elapsed());
- return result;
- }
- wctx.AddElapsedCycles(ActorSystemIndex, timeTracker.Elapsed());
- cpu.LoadLog.RegisterBusyPeriod(GetCycleCountFast());
- bool wakeup;
- do {
- wakeup = cpu.BlockedWait(result, Config.Balancer.PeriodUs * 1000);
- wctx.AddParkedCycles(timeTracker.Elapsed());
- } while (!wakeup);
- cpu.LoadLog.RegisterIdlePeriod(GetCycleCountFast());
- return result;
- }
-
- void TUnitedWorkers::GetCurrentStats(TPoolId pool, TVector<TExecutorThreadStats>& statsCopy) const {
- size_t idx = 1;
- statsCopy.resize(idx + Pools[pool].WakeOrderCpus.size());
- for (TCpu* cpu : Pools[pool].WakeOrderCpus) {
- TExecutorThreadStats& s = statsCopy[idx++];
- s = TExecutorThreadStats();
- s.Aggregate(cpu->PoolStats[pool]);
- }
- }
-
- TUnitedExecutorPool::TUnitedExecutorPool(const TUnitedExecutorPoolConfig& cfg, TUnitedWorkers* united)
- : TExecutorPoolBaseMailboxed(cfg.PoolId)
- , United(united)
- , PoolName(cfg.PoolName)
- {
- United->SetupPool(TPoolId(cfg.PoolId), this, MailboxTable.Get());
- }
-
- void TUnitedExecutorPool::Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) {
- ActorSystem = actorSystem;
-
- // Schedule readers are initialized through TUnitedWorkers::Prepare
- *scheduleReaders = nullptr;
- *scheduleSz = 0;
- }
-
- void TUnitedExecutorPool::Start() {
- // workers are actually started in TUnitedWorkers::Start()
- }
-
- void TUnitedExecutorPool::PrepareStop() {
- }
-
- void TUnitedExecutorPool::Shutdown() {
- // workers are actually joined in TUnitedWorkers::Shutdown()
- }
-
- TAffinity* TUnitedExecutorPool::Affinity() const {
- Y_ABORT(); // should never be called, TCpuExecutorPool is used instead
- }
-
- ui32 TUnitedExecutorPool::GetThreads() const {
- return 0;
- }
-
- ui32 TUnitedExecutorPool::GetReadyActivation(TWorkerContext&, ui64) {
- Y_ABORT(); // should never be called, TCpu*ExecutorPool is used instead
- }
-
- inline void TUnitedExecutorPool::ScheduleActivation(ui32 activation) {
- TUnitedExecutorPool::ScheduleActivationEx(activation, AtomicIncrement(ActivationsRevolvingCounter));
- }
-
- inline void TUnitedExecutorPool::SpecificScheduleActivation(ui32 activation) {
- TUnitedExecutorPool::ScheduleActivation(activation);
- }
-
- inline void TUnitedExecutorPool::ScheduleActivationEx(ui32 activation, ui64 revolvingCounter) {
- United->PushActivation(PoolId, activation, revolvingCounter);
- }
-
- void TUnitedExecutorPool::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) {
- TUnitedExecutorPool::Schedule(deadline - ActorSystem->Timestamp(), ev, cookie, workerId);
- }
-
- void TUnitedExecutorPool::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) {
- Y_DEBUG_ABORT_UNLESS(workerId < United->GetWorkerCount());
- const auto current = ActorSystem->Monotonic();
- if (deadline < current) {
- deadline = current;
- }
- United->GetScheduleWriter(workerId)->Push(deadline.MicroSeconds(), ev.Release(), cookie);
- }
-
- void TUnitedExecutorPool::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) {
- Y_DEBUG_ABORT_UNLESS(workerId < United->GetWorkerCount());
- const auto deadline = ActorSystem->Monotonic() + delta;
- United->GetScheduleWriter(workerId)->Push(deadline.MicroSeconds(), ev.Release(), cookie);
- }
-
- void TUnitedExecutorPool::GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const {
- Y_UNUSED(poolStats);
- if (statsCopy.empty()) {
- statsCopy.resize(1);
- }
- statsCopy[0] = TExecutorThreadStats();
- statsCopy[0].Aggregate(Stats);
- United->GetCurrentStats(PoolId, statsCopy);
- }
-}
diff --git a/library/cpp/actors/core/executor_pool_united.h b/library/cpp/actors/core/executor_pool_united.h
deleted file mode 100644
index c0563a9053..0000000000
--- a/library/cpp/actors/core/executor_pool_united.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-
-#include "actorsystem.h"
-#include "balancer.h"
-#include "scheduler_queue.h"
-#include "executor_pool_base.h"
-
-#include <library/cpp/actors/util/unordered_cache.h>
-
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-#include <library/cpp/actors/util/cpu_load_log.h>
-#include <library/cpp/actors/util/unordered_cache.h>
-#include <library/cpp/containers/stack_vector/stack_vec.h>
-
-#include <util/generic/noncopyable.h>
-
-namespace NActors {
- class TMailboxTable;
-
- class TUnitedExecutorPool: public TExecutorPoolBaseMailboxed {
- TUnitedWorkers* United;
- const TString PoolName;
- TAtomic ActivationsRevolvingCounter = 0;
- public:
- TUnitedExecutorPool(const TUnitedExecutorPoolConfig& cfg, TUnitedWorkers* united);
-
- void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) override;
- void Start() override;
- void PrepareStop() override;
- void Shutdown() override;
-
- TAffinity* Affinity() const override;
- ui32 GetThreads() const override;
- ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingReadCounter) override;
- void ScheduleActivation(ui32 activation) override;
- void SpecificScheduleActivation(ui32 activation) override;
- void ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) override;
- void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override;
- void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override;
- void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override;
-
- void GetCurrentStats(TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const override;
-
- TString GetName() const override {
- return PoolName;
- }
- };
-}
diff --git a/library/cpp/actors/core/executor_pool_united_ut.cpp b/library/cpp/actors/core/executor_pool_united_ut.cpp
deleted file mode 100644
index df3e2d29d8..0000000000
--- a/library/cpp/actors/core/executor_pool_united_ut.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-#include "actorsystem.h"
-#include "executor_pool_basic.h"
-#include "hfunc.h"
-#include "scheduler_basic.h"
-
-#include <library/cpp/actors/util/should_continue.h>
-
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/actors/protos/unittests.pb.h>
-
-using namespace NActors;
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct TEvMsg : public NActors::TEventBase<TEvMsg, 10347> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvMsg, "ExecutorPoolTest: Msg");
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-inline ui64 DoTimedWork(ui64 workUs) {
- ui64 startUs = ThreadCPUTime();
- ui64 endUs = startUs + workUs;
- ui64 nowUs = startUs;
- do {
- ui64 endTs = GetCycleCountFast() + Us2Ts(endUs - nowUs);
- while (GetCycleCountFast() <= endTs) {}
- nowUs = ThreadCPUTime();
- } while (nowUs <= endUs);
- return nowUs - startUs;
-}
-
-class TTestSenderActor : public IActorCallback {
-private:
- using EActivityType = IActor::EActivityType ;
- using EActorActivity = IActor::EActorActivity;
-
-private:
- TAtomic Counter;
- TActorId Receiver;
-
- std::function<void(void)> Action;
-
-public:
- TTestSenderActor(std::function<void(void)> action = [](){},
- EActivityType activityType = EActorActivity::OTHER)
- : IActorCallback(static_cast<TReceiveFunc>(&TTestSenderActor::Execute), activityType)
- , Action(action)
- {}
-
- void Start(TActorId receiver, size_t count) {
- AtomicSet(Counter, count);
- Receiver = receiver;
- }
-
- void Stop() {
- while (true) {
- if (GetCounter() == 0) {
- break;
- }
-
- Sleep(TDuration::MilliSeconds(1));
- }
- }
-
- size_t GetCounter() const {
- return AtomicGet(Counter);
- }
-
-private:
- STFUNC(Execute) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvMsg, Handle);
- }
- }
-
- void Handle(TEvMsg::TPtr &ev) {
- Y_UNUSED(ev);
- Action();
- TAtomicBase count = AtomicDecrement(Counter);
- Y_ABORT_UNLESS(count != Max<TAtomicBase>());
- if (count) {
- Send(Receiver, new TEvMsg());
- }
- }
-};
-
-// Single cpu balancer that switches pool on every activation; not thread-safe
-struct TRoundRobinBalancer: public IBalancer {
- TCpuState* State;
- TMap<TPoolId, TPoolId> NextPool;
-
- bool AddCpu(const TCpuAllocation& cpuAlloc, TCpuState* cpu) override {
- State = cpu;
- TPoolId prev = cpuAlloc.AllowedPools.rbegin()->PoolId;
- for (auto& p : cpuAlloc.AllowedPools) {
- NextPool[prev] = p.PoolId;
- prev = p.PoolId;
- }
- return true;
- }
-
- bool TryLock(ui64) override { return true; }
- void SetPoolStats(TPoolId, const TBalancerStats&) override {}
- void Unlock() override {}
-
- void Balance() override {
- TPoolId assigned;
- TPoolId current;
- State->Load(assigned, current);
- State->AssignPool(NextPool[assigned]);
- }
-
- ui64 GetPeriodUs() override {
- return 1000;
- }
-};
-
-void AddUnitedPool(THolder<TActorSystemSetup>& setup, ui32 concurrency = 0) {
- TUnitedExecutorPoolConfig united;
- united.PoolId = setup->GetExecutorsCount();
- united.Concurrency = concurrency;
- setup->CpuManager.United.emplace_back(std::move(united));
-}
-
-THolder<TActorSystemSetup> GetActorSystemSetup(ui32 cpuCount) {
- auto setup = MakeHolder<NActors::TActorSystemSetup>();
- setup->NodeId = 1;
- setup->CpuManager.UnitedWorkers.CpuCount = cpuCount;
- setup->CpuManager.UnitedWorkers.NoRealtime = true; // unavailable in test environment
- setup->Scheduler = new TBasicSchedulerThread(NActors::TSchedulerConfig(512, 0));
- return setup;
-}
-
-Y_UNIT_TEST_SUITE(UnitedExecutorPool) {
-
-#ifdef _linux_
-
- Y_UNIT_TEST(OnePoolManyCpus) {
- const size_t msgCount = 1e4;
- auto setup = GetActorSystemSetup(4);
- AddUnitedPool(setup);
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- auto begin = TInstant::Now();
-
- auto actor = new TTestSenderActor();
- auto actorId = actorSystem.Register(actor);
- actor->Start(actor->SelfId(), msgCount);
- actorSystem.Send(actorId, new TEvMsg());
-
- while (actor->GetCounter()) {
- auto now = TInstant::Now();
- UNIT_ASSERT_C(now - begin < TDuration::Seconds(5), "Counter is " << actor->GetCounter());
-
- Sleep(TDuration::MilliSeconds(1));
- }
-
- TVector<TExecutorThreadStats> stats;
- TExecutorPoolStats poolStats;
- actorSystem.GetPoolStats(0, poolStats, stats);
- // Sum all per-thread counters into the 0th element
- for (ui32 idx = 1; idx < stats.size(); ++idx) {
- stats[0].Aggregate(stats[idx]);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(stats[0].SentEvents, msgCount - 1);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ReceivedEvents, msgCount);
- //UNIT_ASSERT_VALUES_EQUAL(stats[0].PreemptedEvents, 0); // depends on execution time and system load, so may be non-zero
- UNIT_ASSERT_VALUES_EQUAL(stats[0].NonDeliveredEvents, 0);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].EmptyMailboxActivation, 0);
- //UNIT_ASSERT_VALUES_EQUAL(stats[0].CpuUs, 0); // depends on total duration of test, so undefined
- UNIT_ASSERT(stats[0].ElapsedTicks > 0);
- //UNIT_ASSERT(stats[0].ParkedTicks == 0); // per-pool parked time does not make sense for united pools
- UNIT_ASSERT_VALUES_EQUAL(stats[0].BlockedTicks, 0);
- UNIT_ASSERT(stats[0].ActivationTimeHistogram.TotalSamples >= msgCount / TBasicExecutorPoolConfig::DEFAULT_EVENTS_PER_MAILBOX);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].EventDeliveryTimeHistogram.TotalSamples, msgCount);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].EventProcessingCountHistogram.TotalSamples, msgCount);
- UNIT_ASSERT(stats[0].EventProcessingTimeHistogram.TotalSamples > 0);
- UNIT_ASSERT(stats[0].ElapsedTicksByActivity[NActors::TActorTypeOperator::GetOtherActivityIndex()] > 0);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ReceivedEventsByActivity[NActors::TActorTypeOperator::GetOtherActivityIndex()], msgCount);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ActorsAliveByActivity[NActors::TActorTypeOperator::GetOtherActivityIndex()], 1);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ScheduledEventsByActivity[NActors::TActorTypeOperator::GetOtherActivityIndex()], 0);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PoolActorRegistrations, 1);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PoolDestroyedActors, 0);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PoolAllocatedMailboxes, 4095); // one line
- UNIT_ASSERT(stats[0].MailboxPushedOutByTime + stats[0].MailboxPushedOutByEventCount + stats[0].MailboxPushedOutBySoftPreemption >= msgCount / TBasicExecutorPoolConfig::DEFAULT_EVENTS_PER_MAILBOX);
- }
-
- Y_UNIT_TEST(ManyPoolsOneSharedCpu) {
- const size_t msgCount = 1e4;
- const size_t pools = 4;
- auto setup = GetActorSystemSetup(1);
- for (size_t pool = 0; pool < pools; pool++) {
- AddUnitedPool(setup);
- }
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- auto begin = TInstant::Now();
-
- TVector<TTestSenderActor*> actors;
- for (size_t pool = 0; pool < pools; pool++) {
- auto actor = new TTestSenderActor();
- auto actorId = actorSystem.Register(actor, TMailboxType::HTSwap, pool);
- actor->Start(actor->SelfId(), msgCount);
- actorSystem.Send(actorId, new TEvMsg());
- actors.push_back(actor);
- }
-
- while (true) {
- size_t left = 0;
- for (auto actor : actors) {
- left += actor->GetCounter();
- }
- if (left == 0) {
- break;
- }
- auto now = TInstant::Now();
- UNIT_ASSERT_C(now - begin < TDuration::Seconds(5), "left " << left);
- Sleep(TDuration::MilliSeconds(1));
- }
-
- for (size_t pool = 0; pool < pools; pool++) {
- TVector<TExecutorThreadStats> stats;
- TExecutorPoolStats poolStats;
- actorSystem.GetPoolStats(pool, poolStats, stats);
- // Sum all per-thread counters into the 0th element
- for (ui32 idx = 1; idx < stats.size(); ++idx) {
- stats[0].Aggregate(stats[idx]);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ReceivedEvents, msgCount);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PoolActorRegistrations, 1);
- }
- }
-
- Y_UNIT_TEST(ManyPoolsOneAssignedCpu) {
- const size_t msgCount = 1e4;
- const size_t pools = 4;
- auto setup = GetActorSystemSetup(1);
- setup->Balancer.Reset(new TRoundRobinBalancer());
- for (size_t pool = 0; pool < pools; pool++) {
- AddUnitedPool(setup);
- }
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- auto begin = TInstant::Now();
-
- TVector<TTestSenderActor*> actors;
- for (size_t pool = 0; pool < pools; pool++) {
- auto actor = new TTestSenderActor();
- auto actorId = actorSystem.Register(actor, TMailboxType::HTSwap, pool);
- actor->Start(actor->SelfId(), msgCount);
- actorSystem.Send(actorId, new TEvMsg());
- actors.push_back(actor);
- }
-
- while (true) {
- size_t left = 0;
- for (auto actor : actors) {
- left += actor->GetCounter();
- }
- if (left == 0) {
- break;
- }
- auto now = TInstant::Now();
- UNIT_ASSERT_C(now - begin < TDuration::Seconds(5), "left " << left);
- Sleep(TDuration::MilliSeconds(1));
- }
-
- for (size_t pool = 0; pool < pools; pool++) {
- TVector<TExecutorThreadStats> stats;
- TExecutorPoolStats poolStats;
- actorSystem.GetPoolStats(pool, poolStats, stats);
- // Sum all per-thread counters into the 0th element
- for (ui32 idx = 1; idx < stats.size(); ++idx) {
- stats[0].Aggregate(stats[idx]);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ReceivedEvents, msgCount);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PoolActorRegistrations, 1);
- }
- }
-
- Y_UNIT_TEST(ManyPoolsOneCpuSlowEvents) {
- const size_t msgCount = 3;
- const size_t pools = 4;
- auto setup = GetActorSystemSetup(1);
- for (size_t pool = 0; pool < pools; pool++) {
- AddUnitedPool(setup);
- }
- TActorSystem actorSystem(setup);
- actorSystem.Start();
-
- auto begin = TInstant::Now();
-
- TVector<TTestSenderActor*> actors;
- for (size_t pool = 0; pool < pools; pool++) {
- auto actor = new TTestSenderActor([]() {
- DoTimedWork(100'000);
- });
- auto actorId = actorSystem.Register(actor, TMailboxType::HTSwap, pool);
- actor->Start(actor->SelfId(), msgCount);
- actorSystem.Send(actorId, new TEvMsg());
- actors.push_back(actor);
- }
-
- while (true) {
- size_t left = 0;
- for (auto actor : actors) {
- left += actor->GetCounter();
- }
- if (left == 0) {
- break;
- }
- auto now = TInstant::Now();
- UNIT_ASSERT_C(now - begin < TDuration::Seconds(15), "left " << left);
- Sleep(TDuration::MilliSeconds(1));
- }
-
- for (size_t pool = 0; pool < pools; pool++) {
- TVector<TExecutorThreadStats> stats;
- TExecutorPoolStats poolStats;
- actorSystem.GetPoolStats(pool, poolStats, stats);
- // Sum all per-thread counters into the 0th element
- for (ui32 idx = 1; idx < stats.size(); ++idx) {
- stats[0].Aggregate(stats[idx]);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(stats[0].ReceivedEvents, msgCount);
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PreemptedEvents, msgCount); // every 100ms event should be preempted
- UNIT_ASSERT_VALUES_EQUAL(stats[0].PoolActorRegistrations, 1);
- }
- }
-
-#endif
-
-}
diff --git a/library/cpp/actors/core/executor_pool_united_workers.h b/library/cpp/actors/core/executor_pool_united_workers.h
deleted file mode 100644
index c683ae7d9f..0000000000
--- a/library/cpp/actors/core/executor_pool_united_workers.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include "balancer.h"
-#include "scheduler_queue.h"
-
-#include <library/cpp/actors/actor_type/indexes.h>
-#include <library/cpp/actors/util/cpu_load_log.h>
-#include <library/cpp/actors/util/datetime.h>
-#include <util/generic/noncopyable.h>
-
-namespace NActors {
- class TActorSystem;
- class TMailboxTable;
-
- class TUnitedWorkers: public TNonCopyable {
- struct TWorker;
- struct TPool;
- struct TCpu;
-
- i16 WorkerCount;
- TArrayHolder<TWorker> Workers; // indexed by WorkerId
- size_t PoolCount;
- TArrayHolder<TPool> Pools; // indexed by PoolId, so may include not used (not united) pools
- size_t CpuCount;
- TArrayHolder<TCpu> Cpus; // indexed by CpuId, so may include not allocated CPUs
-
- IBalancer* Balancer; // external pool cpu balancer
-
- TUnitedWorkersConfig Config;
- TCpuAllocationConfig Allocation;
-
- volatile bool StopFlag = false;
- TMinusOneCpuEstimator<1024> MinusOneCpuEstimator;
- const ui32 ActorSystemIndex = NActors::TActorTypeOperator::GetActorSystemIndex();
- public:
- TUnitedWorkers(
- const TUnitedWorkersConfig& config,
- const TVector<TUnitedExecutorPoolConfig>& unitedPools,
- const TCpuAllocationConfig& allocation,
- IBalancer* balancer);
- ~TUnitedWorkers();
- void Prepare(TActorSystem* actorSystem, TVector<NSchedulerQueue::TReader*>& scheduleReaders);
- void Start();
- void PrepareStop();
- void Shutdown();
-
- bool IsStopped() const {
- return RelaxedLoad(&StopFlag);
- }
-
- TWorkerId GetWorkerCount() const {
- return WorkerCount;
- }
-
- // Returns thread id of a worker
- TThreadId GetWorkerThreadId(TWorkerId workerId) const;
-
- // Returns per worker schedule writers
- NSchedulerQueue::TWriter* GetScheduleWriter(TWorkerId workerId) const;
-
- // Sets executor for specified pool
- void SetupPool(TPoolId pool, IExecutorPool* executorPool, TMailboxTable* mailboxTable);
-
- // Add activation of newly scheduled mailbox and wake cpu to execute it if required
- void PushActivation(TPoolId pool, ui32 activation, ui64 revolvingCounter);
-
- // Try acquire pending token. Must be done before execution
- bool TryAcquireToken(TPoolId pool);
-
- // Try to wake idle cpu waiting for tokens on specified pool
- void TryWake(TPoolId pool);
-
- // Get activation from pool; requires pool's token
- void BeginExecution(TPoolId pool, ui32& activation, ui64 revolvingCounter);
-
- // Stop currently active execution and start new one if token is available
- // NOTE: Reuses token if it's not destroyed
- bool NextExecution(TPoolId pool, ui32& activation, ui64 revolvingCounter);
-
- // Stop active execution
- void StopExecution(TPoolId pool);
-
- // Runs balancer to assign pools to cpus
- void Balance();
-
- // Returns pool to be executed by worker or `CpuShared`
- TPoolId AssignedPool(TWorkerContext& wctx);
-
- // Checks if balancer has assigned another pool for worker's cpu
- bool IsPoolReassigned(TWorkerContext& wctx);
-
- // Switch worker context into specified pool
- void SwitchPool(TWorkerContext& wctx, ui64 softDeadlineTs);
-
- // Wait for tokens from any pool allowed on specified cpu
- TPoolId Idle(TPoolId assigned, TWorkerContext& wctx);
-
- // Fill stats for specified pool
- void GetCurrentStats(TPoolId pool, TVector<TExecutorThreadStats>& statsCopy) const;
-
- private:
- TPoolId WaitSequence(TCpu& cpu, TWorkerContext& wctx, TTimeTracker& timeTracker);
- };
-}
diff --git a/library/cpp/actors/core/executor_thread.cpp b/library/cpp/actors/core/executor_thread.cpp
deleted file mode 100644
index 4aab7b3e31..0000000000
--- a/library/cpp/actors/core/executor_thread.cpp
+++ /dev/null
@@ -1,714 +0,0 @@
-#include "executor_thread.h"
-#include "actorsystem.h"
-#include "actor.h"
-#include "callstack.h"
-#include "mailbox.h"
-#include "event.h"
-#include "events.h"
-#include "executor_pool_base.h"
-#include "probes.h"
-
-#include <library/cpp/actors/prof/tag.h>
-#include <library/cpp/actors/util/affinity.h>
-#include <library/cpp/actors/util/datetime.h>
-#include <library/cpp/actors/util/thread.h>
-
-#ifdef BALLOC
-#include <library/cpp/balloc/optional/operators.h>
-#endif
-
-#ifdef _linux_
-#include <sys/syscall.h>
-#include <unistd.h>
-#endif
-
-#include <util/system/type_name.h>
-#include <util/system/datetime.h>
-
-LWTRACE_USING(ACTORLIB_PROVIDER)
-
-namespace NActors {
- constexpr TDuration TExecutorThread::DEFAULT_TIME_PER_MAILBOX;
-
- TExecutorThread::TExecutorThread(
- TWorkerId workerId,
- TWorkerId cpuId,
- TActorSystem* actorSystem,
- IExecutorPool* executorPool,
- TMailboxTable* mailboxTable,
- const TString& threadName,
- TDuration timePerMailbox,
- ui32 eventsPerMailbox)
- : ActorSystem(actorSystem)
- , ExecutorPool(executorPool)
- , Ctx(workerId, cpuId)
- , ThreadName(threadName)
- , IsUnitedWorker(true)
- , TimePerMailbox(timePerMailbox)
- , EventsPerMailbox(eventsPerMailbox)
- {
- Ctx.Switch(
- ExecutorPool,
- mailboxTable,
- NHPTimer::GetClockRate() * timePerMailbox.SecondsFloat(),
- eventsPerMailbox,
- ui64(-1), // infinite soft deadline
- &Ctx.WorkerStats);
- }
-
- TExecutorThread::TExecutorThread(TWorkerId workerId,
- TActorSystem* actorSystem,
- TVector<IExecutorPool*> executorPools,
- const TString& threadName,
- ui64 softProcessingDurationTs,
- TDuration timePerMailbox,
- ui32 eventsPerMailbox)
- : ActorSystem(actorSystem)
- , AvailableExecutorPools(executorPools)
- , Ctx(workerId, 0)
- , ThreadName(threadName)
- , IsUnitedWorker(false)
- , TimePerMailbox(timePerMailbox)
- , EventsPerMailbox(eventsPerMailbox)
- , SoftProcessingDurationTs(softProcessingDurationTs)
- {}
-
-
-
- TExecutorThread::~TExecutorThread()
- { }
-
- void TExecutorThread::UnregisterActor(TMailboxHeader* mailbox, TActorId actorId) {
- Y_DEBUG_ABORT_UNLESS(IsUnitedWorker || actorId.PoolID() == ExecutorPool->PoolId && ExecutorPool->ResolveMailbox(actorId.Hint()) == mailbox);
- IActor* actor = mailbox->DetachActor(actorId.LocalId());
- Ctx.DecrementActorsAliveByActivity(actor->GetActivityType());
- DyingActors.push_back(THolder(actor));
- }
-
- void TExecutorThread::DropUnregistered() {
-#if defined(ACTORSLIB_COLLECT_EXEC_STATS)
- if (ActorSystem->MonitorStuckActors()) {
- if (auto *pool = dynamic_cast<TExecutorPoolBaseMailboxed*>(ExecutorPool)) {
- with_lock (pool->StuckObserverMutex) {
- for (const auto& actor : DyingActors) {
- const size_t i = actor->StuckIndex;
- auto& actorPtr = pool->Actors[i];
- actorPtr = pool->Actors.back();
- actorPtr->StuckIndex = i;
- pool->Actors.pop_back();
- pool->DeadActorsUsage.emplace_back(actor->GetActivityType(), actor->GetUsage(GetCycleCountFast()));
- }
- }
- }
- }
-#endif
- DyingActors.clear(); // here is actual destruction of actors
- }
-
- void TExecutorThread::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) {
- ++CurrentActorScheduledEventsCounter;
- Ctx.Executor->Schedule(deadline, ev, cookie, Ctx.WorkerId);
- }
-
- void TExecutorThread::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) {
- ++CurrentActorScheduledEventsCounter;
- Ctx.Executor->Schedule(deadline, ev, cookie, Ctx.WorkerId);
- }
-
- void TExecutorThread::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) {
- ++CurrentActorScheduledEventsCounter;
- Ctx.Executor->Schedule(delta, ev, cookie, Ctx.WorkerId);
- }
-
- template <class T>
- inline TString SafeTypeName(const T* t) {
- if (t == nullptr) {
- return "nullptr";
- }
- try {
- return TypeName(*t);
- } catch (...) {
- return "unknown-type";
- }
- }
-
- inline void LwTraceSlowDelivery(IEventHandle* ev, const std::type_info* actorType, ui32 poolId, const TActorId& currentRecipient,
- double delivMs, double sinceActivationMs, ui32 eventsExecutedBefore) {
- LWPROBE(EventSlowDelivery,
- poolId,
- delivMs,
- sinceActivationMs,
- eventsExecutedBefore,
- ev && ev->HasEvent() ? ev->GetTypeName() : (ev ? ToString(ev->Type) : TString("nullptr")),
- currentRecipient.ToString(),
- SafeTypeName(actorType));
- }
-
- inline void LwTraceSlowEvent(IEventHandle* ev, ui32 evTypeForTracing, const std::type_info* actorType, ui32 poolId,
- const TActorId& currentRecipient, double eventMs) {
- // Event could have been destroyed by actor->Receive();
- LWPROBE(SlowEvent,
- poolId,
- eventMs,
- ev && ev->HasEvent() ? ev->GetTypeName() : ToString(evTypeForTracing),
- currentRecipient.ToString(),
- SafeTypeName(actorType));
- }
-
- template <typename TMailbox>
- bool TExecutorThread::Execute(TMailbox* mailbox, ui32 hint, bool isTailExecution) {
- Y_DEBUG_ABORT_UNLESS(DyingActors.empty());
-
- bool reclaimAsFree = false;
-
- if (!isTailExecution) {
- Ctx.HPStart = GetCycleCountFast();
- Ctx.ExecutedEvents = 0;
- }
- NHPTimer::STime hpprev = Ctx.HPStart;
-
- IActor* actor = nullptr;
- const std::type_info* actorType = nullptr;
- ui32 prevActivityType = std::numeric_limits<ui32>::max();
- TActorId recipient;
- bool firstEvent = true;
- bool preempted = false;
- for (; Ctx.ExecutedEvents < Ctx.EventsPerMailbox; ++Ctx.ExecutedEvents) {
- if (TAutoPtr<IEventHandle> evExt = mailbox->Pop()) {
- mailbox->ProcessEvents(mailbox);
- NHPTimer::STime hpnow;
- recipient = evExt->GetRecipientRewrite();
- TActorContext ctx(*mailbox, *this, hpprev, recipient);
- TlsActivationContext = &ctx; // ensure dtor (if any) is called within actor system
- // move for destruct before ctx;
- auto ev = std::move(evExt);
- if (actor = mailbox->FindActor(recipient.LocalId())) {
- // Since actor is not null there should be no exceptions
- actorType = &typeid(*actor);
-
-#ifdef USE_ACTOR_CALLSTACK
- TCallstack::GetTlsCallstack() = ev->Callstack;
- TCallstack::GetTlsCallstack().SetLinesToSkip();
-#endif
- CurrentRecipient = recipient;
- CurrentActorScheduledEventsCounter = 0;
-
- if (firstEvent) {
- double usec = Ctx.AddActivationStats(AtomicLoad(&mailbox->ScheduleMoment), hpprev);
- if (usec > 500) {
- GLOBAL_LWPROBE(ACTORLIB_PROVIDER, SlowActivation, Ctx.PoolId, usec / 1000.0);
- }
- firstEvent = false;
- }
-
- i64 usecDeliv = Ctx.AddEventDeliveryStats(ev->SendTime, hpprev);
- if (usecDeliv > 5000) {
- double sinceActivationMs = NHPTimer::GetSeconds(hpprev - Ctx.HPStart) * 1000.0;
- LwTraceSlowDelivery(ev.Get(), actorType, Ctx.PoolId, CurrentRecipient, NHPTimer::GetSeconds(hpprev - ev->SendTime) * 1000.0, sinceActivationMs, Ctx.ExecutedEvents);
- }
-
- ui32 evTypeForTracing = ev->Type;
-
- ui32 activityType = actor->GetActivityType();
- if (activityType != prevActivityType) {
- prevActivityType = activityType;
- NProfiling::TMemoryTagScope::Reset(activityType);
- }
-
- actor->Receive(ev);
- mailbox->ProcessEvents(mailbox);
- actor->OnDequeueEvent();
-
- size_t dyingActorsCnt = DyingActors.size();
- Ctx.UpdateActorsStats(dyingActorsCnt);
- if (dyingActorsCnt) {
- DropUnregistered();
- mailbox->ProcessEvents(mailbox);
- actor = nullptr;
- }
-
- if (mailbox->IsEmpty()) // was not-free and become free, we must reclaim mailbox
- reclaimAsFree = true;
-
- hpnow = GetCycleCountFast();
- NHPTimer::STime elapsed = Ctx.AddEventProcessingStats(hpprev, hpnow, activityType, CurrentActorScheduledEventsCounter);
- if (elapsed > 1000000) {
- LwTraceSlowEvent(ev.Get(), evTypeForTracing, actorType, Ctx.PoolId, CurrentRecipient, NHPTimer::GetSeconds(elapsed) * 1000.0);
- }
-
- // The actor might have been destroyed
- if (actor)
- actor->AddElapsedTicks(elapsed);
-
- CurrentRecipient = TActorId();
- } else {
- actorType = nullptr;
-
- TAutoPtr<IEventHandle> nonDelivered = IEventHandle::ForwardOnNondelivery(std::move(ev), TEvents::TEvUndelivered::ReasonActorUnknown);
- if (nonDelivered.Get()) {
- ActorSystem->Send(nonDelivered);
- } else {
- Ctx.IncrementNonDeliveredEvents();
- }
- hpnow = GetCycleCountFast();
- }
-
- hpprev = hpnow;
-
- if (TlsThreadContext->CapturedType == ESendingType::Tail) {
- AtomicStore(&mailbox->ScheduleMoment, hpnow);
- Ctx.IncrementMailboxPushedOutByTailSending();
- LWTRACK(MailboxPushedOutByTailSending,
- Ctx.Orbit,
- Ctx.PoolId,
- Ctx.Executor->GetName(),
- Ctx.ExecutedEvents + 1,
- CyclesToDuration(hpnow - Ctx.HPStart),
- Ctx.WorkerId,
- recipient.ToString(),
- SafeTypeName(actorType));
- break;
- }
-
- // Soft preemption in united pool
- if (Ctx.SoftDeadlineTs < (ui64)hpnow) {
- AtomicStore(&mailbox->ScheduleMoment, hpnow);
- Ctx.IncrementMailboxPushedOutBySoftPreemption();
- LWTRACK(MailboxPushedOutBySoftPreemption,
- Ctx.Orbit,
- Ctx.PoolId,
- Ctx.Executor->GetName(),
- Ctx.ExecutedEvents + 1,
- CyclesToDuration(hpnow - Ctx.HPStart),
- Ctx.WorkerId,
- recipient.ToString(),
- SafeTypeName(actorType));
- preempted = true;
- break;
- }
-
- // time limit inside one mailbox passed, let others do some work
- if (hpnow - Ctx.HPStart > (i64)Ctx.TimePerMailboxTs) {
- AtomicStore(&mailbox->ScheduleMoment, hpnow);
- Ctx.IncrementMailboxPushedOutByTime();
- LWTRACK(MailboxPushedOutByTime,
- Ctx.Orbit,
- Ctx.PoolId,
- Ctx.Executor->GetName(),
- Ctx.ExecutedEvents + 1,
- CyclesToDuration(hpnow - Ctx.HPStart),
- Ctx.WorkerId,
- recipient.ToString(),
- SafeTypeName(actorType));
- preempted = true;
- break;
- }
-
- if (Ctx.ExecutedEvents + 1 == Ctx.EventsPerMailbox) {
- AtomicStore(&mailbox->ScheduleMoment, hpnow);
- Ctx.IncrementMailboxPushedOutByEventCount();
- LWTRACK(MailboxPushedOutByEventCount,
- Ctx.Orbit,
- Ctx.PoolId,
- Ctx.Executor->GetName(),
- Ctx.ExecutedEvents + 1,
- CyclesToDuration(hpnow - Ctx.HPStart),
- Ctx.WorkerId,
- recipient.ToString(),
- SafeTypeName(actorType));
- preempted = true;
- break;
- }
- } else {
- if (Ctx.ExecutedEvents == 0)
- Ctx.IncrementEmptyMailboxActivation();
- LWTRACK(MailboxEmpty,
- Ctx.Orbit,
- Ctx.PoolId,
- Ctx.Executor->GetName(),
- Ctx.ExecutedEvents,
- CyclesToDuration(GetCycleCountFast() - Ctx.HPStart),
- Ctx.WorkerId,
- recipient.ToString(),
- SafeTypeName(actor));
- break; // empty queue, leave
- }
- }
-
- NProfiling::TMemoryTagScope::Reset(0);
- TlsActivationContext = nullptr;
- UnlockFromExecution(mailbox, Ctx.Executor, reclaimAsFree, hint, Ctx.WorkerId, RevolvingWriteCounter);
- return preempted;
- }
-
- TThreadId TExecutorThread::GetThreadId() const {
-#ifdef _linux_
- while (AtomicLoad(&ThreadId) == UnknownThreadId) {
- NanoSleep(1000);
- }
-#endif
- return ThreadId;
- }
-
- TWorkerId TExecutorThread::GetWorkerId() const {
- return Ctx.WorkerId;
- }
-
- void TExecutorThread::ProcessExecutorPool(IExecutorPool *pool, bool isSharedThread) {
- ExecutorPool = pool;
- TThreadContext threadCtx;
- TlsThreadContext = &threadCtx;
- TlsThreadContext->Pool = static_cast<IExecutorPool*>(ExecutorPool);
- TlsThreadContext->WorkerId = Ctx.WorkerId;
- pool->Initialize(Ctx);
-
- ExecutorPool->SetRealTimeMode();
- TAffinityGuard affinity(ExecutorPool->Affinity());
-
- NHPTimer::STime hpnow = GetCycleCountFast();
- NHPTimer::STime hpprev = hpnow;
- ui64 execCount = 0;
- ui64 readyActivationCount = 0;
- i64 execCycles = 0;
- i64 nonExecCycles = 0;
-
- bool needToStop = false;
-
- auto executeActivation = [&](ui32 activation, bool isTailExecution) {
- LWTRACK(ActivationBegin, Ctx.Orbit, Ctx.CpuId, Ctx.PoolId, Ctx.WorkerId, NHPTimer::GetSeconds(Ctx.Lease.GetPreciseExpireTs()) * 1e3);
- readyActivationCount++;
- if (TMailboxHeader* header = Ctx.MailboxTable->Get(activation)) {
- if (header->LockForExecution()) {
- hpnow = GetCycleCountFast();
- nonExecCycles += hpnow - hpprev;
- hpprev = hpnow;
-#define EXECUTE_MAILBOX(type) \
- case TMailboxType:: type: \
- { \
- using TMailBox = TMailboxTable:: T ## type ## Mailbox ; \
- if (Execute<TMailBox>(static_cast<TMailBox*>(header), activation, isTailExecution)) { \
- TlsThreadContext->CapturedType = ESendingType::Lazy; \
- } \
- } \
- break \
-// EXECUTE_MAILBOX
- switch (header->Type) {
- EXECUTE_MAILBOX(Simple);
- EXECUTE_MAILBOX(Revolving);
- EXECUTE_MAILBOX(HTSwap);
- EXECUTE_MAILBOX(ReadAsFilled);
- EXECUTE_MAILBOX(TinyReadAsFilled);
- }
-#undef EXECUTE_MAILBOX
- hpnow = GetCycleCountFast();
- i64 currentExecCycles = hpnow - hpprev;
- execCycles += currentExecCycles;
- hpprev = hpnow;
- execCount++;
- if (execCycles + nonExecCycles > 39000000) { // every 15 ms at 2.6GHz, so 1000 items is 15 sec (solomon interval)
- LWPROBE(ExecutorThreadStats, ExecutorPool->PoolId, ExecutorPool->GetName(), Ctx.WorkerId,
- execCount, readyActivationCount,
- NHPTimer::GetSeconds(execCycles) * 1000.0, NHPTimer::GetSeconds(nonExecCycles) * 1000.0);
- execCount = 0;
- readyActivationCount = 0;
- execCycles = 0;
- nonExecCycles = 0;
- Ctx.UpdateThreadTime();
- }
-
- if (isSharedThread && (ui64)hpnow > Ctx.SoftDeadlineTs) {
- needToStop = true;
- }
-
- if (!TlsThreadContext->IsEnoughCpu) {
- Ctx.IncreaseNotEnoughCpuExecutions();
- TlsThreadContext->IsEnoughCpu = true;
- }
- }
- }
- LWTRACK(ActivationEnd, Ctx.Orbit, Ctx.CpuId, Ctx.PoolId, Ctx.WorkerId);
- Ctx.Orbit.Reset();
- };
-
- while (!needToStop && !StopFlag.load(std::memory_order_relaxed)) {
- if (TlsThreadContext->CapturedType == ESendingType::Tail) {
- TlsThreadContext->CapturedType = ESendingType::Lazy;
- ui32 activation = std::exchange(TlsThreadContext->CapturedActivation, 0);
- executeActivation(activation, true);
- continue;
- }
- Ctx.IsNeededToWaitNextActivation = !TlsThreadContext->CapturedActivation && !isSharedThread;
- ui32 activation = ExecutorPool->GetReadyActivation(Ctx, ++RevolvingReadCounter);
- if (!activation) {
- activation = std::exchange(TlsThreadContext->CapturedActivation, 0);
- } else if (TlsThreadContext->CapturedActivation) {
- ui32 capturedActivation = std::exchange(TlsThreadContext->CapturedActivation, 0);
- ExecutorPool->ScheduleActivation(capturedActivation);
- }
- if (!activation) {
- break;
- }
- executeActivation(activation, false);
- }
- }
-
- void* TExecutorThread::ThreadProc() {
-#ifdef _linux_
- pid_t tid = syscall(SYS_gettid);
- AtomicSet(ThreadId, (ui64)tid);
-#endif
-
-#ifdef BALLOC
- ThreadDisableBalloc();
-#endif
-
- if (ThreadName) {
- ::SetCurrentThreadName(ThreadName);
- }
-
-
- std::vector<TExecutorPoolBaseMailboxed*> pools;
- pools.reserve(AvailableExecutorPools.size());
- for (auto pool : AvailableExecutorPools) {
- TExecutorPoolBaseMailboxed* mailboxedPool = dynamic_cast<TExecutorPoolBaseMailboxed*>(pool);
- if (mailboxedPool) {
- pools.push_back(mailboxedPool);
- }
- }
-
- if (pools.size() == 1) {
- ExecutorPool = pools[0];
- Ctx.Switch(
- pools[0],
- pools[0]->MailboxTable.Get(),
- NHPTimer::GetClockRate() * TimePerMailbox.SecondsFloat(),
- EventsPerMailbox,
- GetCycleCountFast() + SoftProcessingDurationTs,
- &Ctx.WorkerStats);
- }
-
- if (pools.size() <= 1) {
- ProcessExecutorPool(ExecutorPool, false);
- } else {
- while (!StopFlag.load(std::memory_order_relaxed)) {
- for (auto pool : pools) {
- Ctx.Switch(
- pool,
- pool->MailboxTable.Get(),
- NHPTimer::GetClockRate() * TimePerMailbox.SecondsFloat(),
- EventsPerMailbox,
- GetCycleCountFast() + SoftProcessingDurationTs,
- &Ctx.WorkerStats);
- Ctx.WorkerId = -1;
- ProcessExecutorPool(pool, true);
- }
- }
- }
-
- return nullptr;
- }
-
- // there must be barrier and check-read with following cas
- // or just cas w/o read.
- // or queue unlocks must be performed with exchange and not generic write
- // TODO: check performance of those options under contention
-
- // placed here in hope for better compiler optimization
-
- bool TMailboxHeader::MarkForSchedule() {
- AtomicBarrier();
- for (;;) {
- const ui32 state = AtomicLoad(&ExecutionState);
- switch (state) {
- case TExecutionState::Inactive:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::Scheduled, TExecutionState::Inactive))
- return true;
- break;
- case TExecutionState::Scheduled:
- return false;
- case TExecutionState::Leaving:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::LeavingMarked, TExecutionState::Leaving))
- return true;
- break;
- case TExecutionState::Executing:
- case TExecutionState::LeavingMarked:
- return false;
- case TExecutionState::Free:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::Free))
- return true;
- break;
- case TExecutionState::FreeScheduled:
- return false;
- case TExecutionState::FreeLeaving:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeLeavingMarked, TExecutionState::FreeLeaving))
- return true;
- break;
- case TExecutionState::FreeExecuting:
- case TExecutionState::FreeLeavingMarked:
- return false;
- default:
- Y_ABORT();
- }
- }
- }
-
- bool TMailboxHeader::LockForExecution() {
- AtomicBarrier(); // strictly speaking here should be AtomicBarrier, but as we got mailboxes from queue - this barrier is already set implicitly and could be removed
- for (;;) {
- const ui32 state = AtomicLoad(&ExecutionState);
- switch (state) {
- case TExecutionState::Inactive:
- return false;
- case TExecutionState::Scheduled:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::Executing, TExecutionState::Scheduled))
- return true;
- break;
- case TExecutionState::Leaving:
- case TExecutionState::Executing:
- case TExecutionState::LeavingMarked:
- return false;
- case TExecutionState::Free:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeExecuting, TExecutionState::Free))
- return true;
- break;
- case TExecutionState::FreeScheduled:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeExecuting, TExecutionState::FreeScheduled))
- return true;
- break;
- case TExecutionState::FreeLeaving:
- case TExecutionState::FreeExecuting:
- case TExecutionState::FreeLeavingMarked:
- return false;
- default:
- Y_ABORT();
- }
- }
- }
-
- bool TMailboxHeader::LockFromFree() {
- AtomicBarrier();
- for (;;) {
- const ui32 state = AtomicLoad(&ExecutionState);
- switch (state) {
- case TExecutionState::Inactive:
- case TExecutionState::Scheduled:
- case TExecutionState::Leaving:
- case TExecutionState::Executing:
- case TExecutionState::LeavingMarked:
- Y_ABORT();
- case TExecutionState::Free:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::Executing, TExecutionState::Free))
- return true;
- break;
- case TExecutionState::FreeScheduled:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::Executing, TExecutionState::FreeScheduled))
- return true;
- break;
- case TExecutionState::FreeLeaving:
- case TExecutionState::FreeExecuting:
- case TExecutionState::FreeLeavingMarked:
- return false;
- default:
- Y_ABORT();
- }
- }
- }
-
- void TMailboxHeader::UnlockFromExecution1() {
- const ui32 state = AtomicLoad(&ExecutionState);
- if (state == TExecutionState::Executing)
- AtomicStore(&ExecutionState, (ui32)TExecutionState::Leaving);
- else if (state == TExecutionState::FreeExecuting)
- AtomicStore(&ExecutionState, (ui32)TExecutionState::FreeLeaving);
- else
- Y_ABORT();
- AtomicBarrier();
- }
-
- bool TMailboxHeader::UnlockFromExecution2(bool wouldReschedule) {
- AtomicBarrier();
- for (;;) {
- const ui32 state = AtomicLoad(&ExecutionState);
- switch (state) {
- case TExecutionState::Inactive:
- case TExecutionState::Scheduled:
- Y_ABORT();
- case TExecutionState::Leaving:
- if (!wouldReschedule) {
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::Inactive, TExecutionState::Leaving))
- return false;
- } else {
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::Scheduled, TExecutionState::Leaving))
- return true;
- }
- break;
- case TExecutionState::Executing:
- Y_ABORT();
- case TExecutionState::LeavingMarked:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::Scheduled, TExecutionState::LeavingMarked))
- return true;
- break;
- case TExecutionState::Free:
- case TExecutionState::FreeScheduled:
- Y_ABORT();
- case TExecutionState::FreeLeaving:
- if (!wouldReschedule) {
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::Free, TExecutionState::FreeLeaving))
- return false;
- } else {
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::FreeLeaving))
- return true;
- }
- break;
- case TExecutionState::FreeExecuting:
- Y_ABORT();
- case TExecutionState::FreeLeavingMarked:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::FreeLeavingMarked))
- return true;
- break;
- default:
- Y_ABORT();
- }
- }
- }
-
- bool TMailboxHeader::UnlockAsFree(bool wouldReschedule) {
- AtomicBarrier();
- for (;;) {
- const ui32 state = AtomicLoad(&ExecutionState);
- switch (state) {
- case TExecutionState::Inactive:
- case TExecutionState::Scheduled:
- Y_ABORT();
- case TExecutionState::Leaving:
- if (!wouldReschedule) {
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::Free, TExecutionState::Leaving))
- return false;
- } else {
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::Leaving))
- return true;
- }
- break;
- case TExecutionState::Executing:
- Y_ABORT();
- case TExecutionState::LeavingMarked:
- if (AtomicUi32Cas(&ExecutionState, TExecutionState::FreeScheduled, TExecutionState::LeavingMarked))
- return true;
- break;
- case TExecutionState::Free:
- case TExecutionState::FreeScheduled:
- case TExecutionState::FreeLeaving:
- case TExecutionState::FreeExecuting:
- case TExecutionState::FreeLeavingMarked:
- Y_ABORT();
- default:
- Y_ABORT();
- }
- }
- }
-
- void TExecutorThread::GetCurrentStats(TExecutorThreadStats& statsCopy) const {
- Ctx.GetCurrentStats(statsCopy);
- }
-
-}
diff --git a/library/cpp/actors/core/executor_thread.h b/library/cpp/actors/core/executor_thread.h
deleted file mode 100644
index b466ad2423..0000000000
--- a/library/cpp/actors/core/executor_thread.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include "event.h"
-#include "callstack.h"
-#include "probes.h"
-#include "worker_context.h"
-#include "log_settings.h"
-
-#include <library/cpp/actors/util/datetime.h>
-
-#include <util/system/thread.h>
-
-namespace NActors {
- class IActor;
- class TActorSystem;
-
- class TExecutorThread: public ISimpleThread {
- public:
- static constexpr TDuration DEFAULT_TIME_PER_MAILBOX =
- TDuration::MilliSeconds(10);
- static constexpr ui32 DEFAULT_EVENTS_PER_MAILBOX = 100;
-
- TExecutorThread(TWorkerId workerId,
- TWorkerId cpuId,
- TActorSystem* actorSystem,
- IExecutorPool* executorPool,
- TMailboxTable* mailboxTable,
- const TString& threadName,
- TDuration timePerMailbox = DEFAULT_TIME_PER_MAILBOX,
- ui32 eventsPerMailbox = DEFAULT_EVENTS_PER_MAILBOX);
-
- TExecutorThread(TWorkerId workerId,
- TActorSystem* actorSystem,
- IExecutorPool* executorPool,
- TMailboxTable* mailboxTable,
- const TString& threadName,
- TDuration timePerMailbox = DEFAULT_TIME_PER_MAILBOX,
- ui32 eventsPerMailbox = DEFAULT_EVENTS_PER_MAILBOX)
- : TExecutorThread(workerId, 0, actorSystem, executorPool, mailboxTable, threadName, timePerMailbox, eventsPerMailbox)
- {}
-
- TExecutorThread(TWorkerId workerId,
- TActorSystem* actorSystem,
- TVector<IExecutorPool*> executorPools,
- const TString& threadName,
- ui64 softProcessingDurationTs,
- TDuration timePerMailbox,
- ui32 eventsPerMailbox);
-
- virtual ~TExecutorThread();
-
- template <ESendingType SendingType = ESendingType::Common>
- TActorId RegisterActor(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>(),
- TActorId parentId = TActorId());
- template <ESendingType SendingType = ESendingType::Common>
- TActorId RegisterActor(IActor* actor, TMailboxHeader* mailbox, ui32 hint, TActorId parentId = TActorId());
- void UnregisterActor(TMailboxHeader* mailbox, TActorId actorId);
- void DropUnregistered();
- 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);
- void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr);
-
- template <ESendingType SendingType = ESendingType::Common>
- bool Send(TAutoPtr<IEventHandle> ev);
-
- void GetCurrentStats(TExecutorThreadStats& statsCopy) const;
-
- TThreadId GetThreadId() const; // blocks, must be called after Start()
- TWorkerId GetWorkerId() const;
-
- private:
- void* ThreadProc();
-
- void ProcessExecutorPool(IExecutorPool *pool, bool isSharedThread);
-
- template <typename TMailbox>
- bool Execute(TMailbox* mailbox, ui32 hint, bool isTailExecution);
-
- public:
- TActorSystem* const ActorSystem;
- std::atomic<bool> StopFlag = false;
-
- private:
- // Pool-specific
- IExecutorPool* ExecutorPool;
- TVector<IExecutorPool*> AvailableExecutorPools;
-
- // Event-specific (currently executing)
- TVector<THolder<IActor>> DyingActors;
- TActorId CurrentRecipient;
- ui64 CurrentActorScheduledEventsCounter = 0;
-
- // Thread-specific
- TWorkerContext Ctx;
- ui64 RevolvingReadCounter = 0;
- ui64 RevolvingWriteCounter = 0;
- const TString ThreadName;
- volatile TThreadId ThreadId = UnknownThreadId;
- bool IsUnitedWorker = false;
-
- TDuration TimePerMailbox;
- ui32 EventsPerMailbox;
- ui64 SoftProcessingDurationTs;
- };
-
- template <typename TMailbox>
- void UnlockFromExecution(TMailbox* mailbox, IExecutorPool* executorPool, bool asFree, ui32 hint, TWorkerId workerId, ui64& revolvingWriteCounter) {
- mailbox->UnlockFromExecution1();
- const bool needReschedule1 = (nullptr != mailbox->Head());
- if (!asFree) {
- if (mailbox->UnlockFromExecution2(needReschedule1)) {
- RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast());
- executorPool->ScheduleActivationEx(hint, ++revolvingWriteCounter);
- }
- } else {
- if (mailbox->UnlockAsFree(needReschedule1)) {
- RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast());
- executorPool->ScheduleActivationEx(hint, ++revolvingWriteCounter);
- }
- executorPool->ReclaimMailbox(TMailbox::MailboxType, hint, workerId, ++revolvingWriteCounter);
- }
- }
-}
diff --git a/library/cpp/actors/core/harmonizer.cpp b/library/cpp/actors/core/harmonizer.cpp
deleted file mode 100644
index 4464603dc8..0000000000
--- a/library/cpp/actors/core/harmonizer.cpp
+++ /dev/null
@@ -1,700 +0,0 @@
-#include "harmonizer.h"
-
-#include "probes.h"
-#include "actorsystem.h"
-#include "executor_pool_basic.h"
-#include "executor_pool_basic_feature_flags.h"
-
-#include <library/cpp/actors/util/cpu_load_log.h>
-#include <library/cpp/actors/util/datetime.h>
-#include <library/cpp/actors/util/intrinsics.h>
-
-#include <util/system/spinlock.h>
-
-#include <algorithm>
-
-namespace NActors {
-
-LWTRACE_USING(ACTORLIB_PROVIDER);
-
-constexpr bool CheckBinaryPower(ui64 value) {
- return !(value & (value - 1));
-}
-
-template <ui8 HistoryBufferSize = 8>
-struct TValueHistory {
- static_assert(CheckBinaryPower(HistoryBufferSize));
-
- double History[HistoryBufferSize] = {0.0};
- ui64 HistoryIdx = 0;
- ui64 LastTs = Max<ui64>();
- double LastUs = 0.0;
- double AccumulatedUs = 0.0;
- ui64 AccumulatedTs = 0;
-
- template <bool WithTail=false>
- double Accumulate(auto op, auto comb, ui8 seconds) {
- double acc = AccumulatedUs;
- size_t idx = HistoryIdx;
- ui8 leftSeconds = seconds;
- if constexpr (!WithTail) {
- idx--;
- leftSeconds--;
- if (idx >= HistoryBufferSize) {
- idx = HistoryBufferSize - 1;
- }
- acc = History[idx];
- }
- do {
- idx--;
- leftSeconds--;
- if (idx >= HistoryBufferSize) {
- idx = HistoryBufferSize - 1;
- }
- if constexpr (WithTail) {
- acc = op(acc, History[idx]);
- } else if (leftSeconds) {
- acc = op(acc, History[idx]);
- } else {
- ui64 tsInSecond = Us2Ts(1'000'000.0);
- acc = op(acc, History[idx] * (tsInSecond - AccumulatedTs) / tsInSecond);
- }
- } while (leftSeconds);
- double duration = 1'000'000.0 * seconds;
- if constexpr (WithTail) {
- duration += Ts2Us(AccumulatedTs);
- }
- return comb(acc, duration);
- }
-
- template <bool WithTail=false>
- double GetAvgPartForLastSeconds(ui8 seconds) {
- auto sum = [](double acc, double value) {
- return acc + value;
- };
- auto avg = [](double sum, double duration) {
- return sum / duration;
- };
- return Accumulate<WithTail>(sum, avg, seconds);
- }
-
- double GetAvgPart() {
- return GetAvgPartForLastSeconds<true>(HistoryBufferSize);
- }
-
- double GetMaxForLastSeconds(ui8 seconds) {
- auto max = [](const double& acc, const double& value) {
- return Max(acc, value);
- };
- auto fst = [](const double& value, const double&) { return value; };
- return Accumulate<false>(max, fst, seconds);
- }
-
- double GetMax() {
- return GetMaxForLastSeconds(HistoryBufferSize);
- }
-
- i64 GetMaxInt() {
- return static_cast<i64>(GetMax());
- }
-
- double GetMinForLastSeconds(ui8 seconds) {
- auto min = [](const double& acc, const double& value) {
- return Min(acc, value);
- };
- auto fst = [](const double& value, const double&) { return value; };
- return Accumulate<false>(min, fst, seconds);
- }
-
- double GetMin() {
- return GetMinForLastSeconds(HistoryBufferSize);
- }
-
- i64 GetMinInt() {
- return static_cast<i64>(GetMin());
- }
-
- void Register(ui64 ts, double valueUs) {
- if (ts < LastTs) {
- LastTs = ts;
- LastUs = valueUs;
- AccumulatedUs = 0.0;
- AccumulatedTs = 0;
- return;
- }
- ui64 lastTs = std::exchange(LastTs, ts);
- ui64 dTs = ts - lastTs;
- double lastUs = std::exchange(LastUs, valueUs);
- double dUs = valueUs - lastUs;
- LWPROBE(RegisterValue, ts, lastTs, dTs, Us2Ts(8'000'000.0), valueUs, lastUs, dUs);
-
- if (dTs > Us2Ts(8'000'000.0)) {
- dUs = dUs * 1'000'000.0 / Ts2Us(dTs);
- for (size_t idx = 0; idx < HistoryBufferSize; ++idx) {
- History[idx] = dUs;
- }
- AccumulatedUs = 0.0;
- AccumulatedTs = 0;
- return;
- }
-
- while (dTs > 0) {
- if (AccumulatedTs + dTs < Us2Ts(1'000'000.0)) {
- AccumulatedTs += dTs;
- AccumulatedUs += dUs;
- break;
- } else {
- ui64 addTs = Us2Ts(1'000'000.0) - AccumulatedTs;
- double addUs = dUs * addTs / dTs;
- dTs -= addTs;
- dUs -= addUs;
- History[HistoryIdx] = AccumulatedUs + addUs;
- HistoryIdx = (HistoryIdx + 1) % HistoryBufferSize;
- AccumulatedUs = 0.0;
- AccumulatedTs = 0;
- }
- }
- }
-};
-
-struct TThreadInfo {
- TValueHistory<8> Consumed;
- TValueHistory<8> Booked;
-};
-
-struct TPoolInfo {
- std::vector<TThreadInfo> ThreadInfo;
- IExecutorPool* Pool = nullptr;
- TBasicExecutorPool* BasicPool = nullptr;
- i16 DefaultThreadCount = 0;
- i16 MinThreadCount = 0;
- i16 MaxThreadCount = 0;
- i16 Priority = 0;
- NMonitoring::TDynamicCounters::TCounterPtr AvgPingCounter;
- NMonitoring::TDynamicCounters::TCounterPtr AvgPingCounterWithSmallWindow;
- ui32 MaxAvgPingUs = 0;
- ui64 LastUpdateTs = 0;
- ui64 NotEnoughCpuExecutions = 0;
- ui64 NewNotEnoughCpuExecutions = 0;
- ui16 LocalQueueSize = NFeatures::TLocalQueuesFeatureFlags::MIN_LOCAL_QUEUE_SIZE;
-
- TAtomic LastFlags = 0; // 0 - isNeedy; 1 - isStarved; 2 - isHoggish
- TAtomic IncreasingThreadsByNeedyState = 0;
- TAtomic IncreasingThreadsByExchange = 0;
- TAtomic DecreasingThreadsByStarvedState = 0;
- TAtomic DecreasingThreadsByHoggishState = 0;
- TAtomic DecreasingThreadsByExchange = 0;
- TAtomic PotentialMaxThreadCount = 0;
-
- TValueHistory<16> Consumed;
- TValueHistory<16> Booked;
-
- TAtomic MaxConsumedCpu = 0;
- TAtomic MinConsumedCpu = 0;
- TAtomic MaxBookedCpu = 0;
- TAtomic MinBookedCpu = 0;
-
- std::unique_ptr<TWaitingStats<ui64>> WaitingStats;
- std::unique_ptr<TWaitingStats<double>> MovingWaitingStats;
-
- double GetBooked(i16 threadIdx);
- double GetlastSecondPoolBooked(i16 threadIdx);
- double GetConsumed(i16 threadIdx);
- double GetlastSecondPoolConsumed(i16 threadIdx);
- TCpuConsumption PullStats(ui64 ts);
- i16 GetThreadCount();
- void SetThreadCount(i16 threadCount);
- bool IsAvgPingGood();
-};
-
-double TPoolInfo::GetBooked(i16 threadIdx) {
- if ((size_t)threadIdx < ThreadInfo.size()) {
- return ThreadInfo[threadIdx].Booked.GetAvgPart();
- }
- return 0.0;
-}
-
-double TPoolInfo::GetlastSecondPoolBooked(i16 threadIdx) {
- if ((size_t)threadIdx < ThreadInfo.size()) {
- return ThreadInfo[threadIdx].Booked.GetAvgPartForLastSeconds(1);
- }
- return 0.0;
-}
-
-double TPoolInfo::GetConsumed(i16 threadIdx) {
- if ((size_t)threadIdx < ThreadInfo.size()) {
- return ThreadInfo[threadIdx].Consumed.GetAvgPart();
- }
- return 0.0;
-}
-
-double TPoolInfo::GetlastSecondPoolConsumed(i16 threadIdx) {
- if ((size_t)threadIdx < ThreadInfo.size()) {
- return ThreadInfo[threadIdx].Consumed.GetAvgPartForLastSeconds(1);
- }
- return 0.0;
-}
-
-#define UNROLL_HISTORY(history) (history)[0], (history)[1], (history)[2], (history)[3], (history)[4], (history)[5], (history)[6], (history)[7]
-TCpuConsumption TPoolInfo::PullStats(ui64 ts) {
- TCpuConsumption acc;
- for (i16 threadIdx = 0; threadIdx < MaxThreadCount; ++threadIdx) {
- TThreadInfo &threadInfo = ThreadInfo[threadIdx];
- TCpuConsumption cpuConsumption = Pool->GetThreadCpuConsumption(threadIdx);
- acc.Add(cpuConsumption);
- threadInfo.Consumed.Register(ts, cpuConsumption.ConsumedUs);
- LWPROBE(SavedValues, Pool->PoolId, Pool->GetName(), "consumed", UNROLL_HISTORY(threadInfo.Consumed.History));
- threadInfo.Booked.Register(ts, cpuConsumption.BookedUs);
- LWPROBE(SavedValues, Pool->PoolId, Pool->GetName(), "booked", UNROLL_HISTORY(threadInfo.Booked.History));
- }
- Consumed.Register(ts, acc.ConsumedUs);
- RelaxedStore(&MaxConsumedCpu, Consumed.GetMaxInt());
- RelaxedStore(&MinConsumedCpu, Consumed.GetMinInt());
- Booked.Register(ts, acc.BookedUs);
- RelaxedStore(&MaxBookedCpu, Booked.GetMaxInt());
- RelaxedStore(&MinBookedCpu, Booked.GetMinInt());
- NewNotEnoughCpuExecutions = acc.NotEnoughCpuExecutions - NotEnoughCpuExecutions;
- NotEnoughCpuExecutions = acc.NotEnoughCpuExecutions;
- if (WaitingStats && BasicPool) {
- WaitingStats->Clear();
- BasicPool->GetWaitingStats(*WaitingStats);
- if constexpr (!NFeatures::TSpinFeatureFlags::CalcPerThread) {
- MovingWaitingStats->Add(*WaitingStats, 0.8, 0.2);
- }
- }
- return acc;
-}
-#undef UNROLL_HISTORY
-
-i16 TPoolInfo::GetThreadCount() {
- return Pool->GetThreadCount();
-}
-
-void TPoolInfo::SetThreadCount(i16 threadCount) {
- Pool->SetThreadCount(threadCount);
-}
-
-bool TPoolInfo::IsAvgPingGood() {
- bool res = true;
- if (AvgPingCounter) {
- res &= *AvgPingCounter > MaxAvgPingUs;
- }
- if (AvgPingCounterWithSmallWindow) {
- res &= *AvgPingCounterWithSmallWindow > MaxAvgPingUs;
- }
- return res;
-}
-
-class THarmonizer: public IHarmonizer {
-private:
- std::atomic<bool> IsDisabled = false;
- TSpinLock Lock;
- std::atomic<ui64> NextHarmonizeTs = 0;
- std::vector<TPoolInfo> Pools;
- std::vector<ui16> PriorityOrder;
-
- TValueHistory<16> Consumed;
- TValueHistory<16> Booked;
-
- TAtomic MaxConsumedCpu = 0;
- TAtomic MinConsumedCpu = 0;
- TAtomic MaxBookedCpu = 0;
- TAtomic MinBookedCpu = 0;
-
- std::atomic<double> AvgAwakeningTimeUs = 0;
- std::atomic<double> AvgWakingUpTimeUs = 0;
-
- void PullStats(ui64 ts);
- void HarmonizeImpl(ui64 ts);
- void CalculatePriorityOrder();
-public:
- THarmonizer(ui64 ts);
- virtual ~THarmonizer();
- double Rescale(double value) const;
- void Harmonize(ui64 ts) override;
- void DeclareEmergency(ui64 ts) override;
- void AddPool(IExecutorPool* pool, TSelfPingInfo *pingInfo) override;
- void Enable(bool enable) override;
- TPoolHarmonizerStats GetPoolStats(i16 poolId) const override;
- THarmonizerStats GetStats() const override;
-};
-
-THarmonizer::THarmonizer(ui64 ts) {
- NextHarmonizeTs = ts;
-}
-
-THarmonizer::~THarmonizer() {
-}
-
-double THarmonizer::Rescale(double value) const {
- return Max(0.0, Min(1.0, value * (1.0/0.9)));
-}
-
-void THarmonizer::PullStats(ui64 ts) {
- TCpuConsumption acc;
- for (TPoolInfo &pool : Pools) {
- TCpuConsumption consumption = pool.PullStats(ts);
- acc.Add(consumption);
- }
- Consumed.Register(ts, acc.ConsumedUs);
- RelaxedStore(&MaxConsumedCpu, Consumed.GetMaxInt());
- RelaxedStore(&MinConsumedCpu, Consumed.GetMinInt());
- Booked.Register(ts, acc.BookedUs);
- RelaxedStore(&MaxBookedCpu, Booked.GetMaxInt());
- RelaxedStore(&MinBookedCpu, Booked.GetMinInt());
-}
-
-Y_FORCE_INLINE bool IsStarved(double consumed, double booked) {
- return Max(consumed, booked) > 0.1 && consumed < booked * 0.7;
-}
-
-Y_FORCE_INLINE bool IsHoggish(double booked, ui16 currentThreadCount) {
- return booked < currentThreadCount - 1;
-}
-
-void THarmonizer::HarmonizeImpl(ui64 ts) {
- bool isStarvedPresent = false;
- double booked = 0.0;
- double consumed = 0.0;
- double lastSecondBooked = 0.0;
- i64 beingStopped = 0;
- i64 total = 0;
- TStackVec<size_t, 8> needyPools;
- TStackVec<size_t, 8> hoggishPools;
- TStackVec<bool, 8> isNeedyByPool;
-
- size_t sumOfAdditionalThreads = 0;
-
-
- ui64 TotalWakingUpTime = 0;
- ui64 TotalWakingUps = 0;
- ui64 TotalAwakeningTime = 0;
- ui64 TotalAwakenings = 0;
- for (size_t poolIdx = 0; poolIdx < Pools.size(); ++poolIdx) {
- TPoolInfo& pool = Pools[poolIdx];
- if (pool.WaitingStats) {
- TotalWakingUpTime += pool.WaitingStats->WakingUpTotalTime;
- TotalWakingUps += pool.WaitingStats->WakingUpCount;
- TotalAwakeningTime += pool.WaitingStats->AwakingTotalTime;
- TotalAwakenings += pool.WaitingStats->AwakingCount;
- }
- }
-
- constexpr ui64 knownAvgWakingUpTime = TWaitingStatsConstants::KnownAvgWakingUpTime;
- constexpr ui64 knownAvgAwakeningUpTime = TWaitingStatsConstants::KnownAvgAwakeningTime;
-
- ui64 realAvgWakingUpTime = (TotalWakingUps ? TotalWakingUpTime / TotalWakingUps : knownAvgWakingUpTime);
- ui64 avgWakingUpTime = realAvgWakingUpTime;
- if (avgWakingUpTime > 2 * knownAvgWakingUpTime || !realAvgWakingUpTime) {
- avgWakingUpTime = knownAvgWakingUpTime;
- }
- AvgWakingUpTimeUs = Ts2Us(avgWakingUpTime);
-
- ui64 realAvgAwakeningTime = (TotalAwakenings ? TotalAwakeningTime / TotalAwakenings : knownAvgAwakeningUpTime);
- ui64 avgAwakeningTime = realAvgAwakeningTime;
- if (avgAwakeningTime > 2 * knownAvgAwakeningUpTime || !realAvgAwakeningTime) {
- avgAwakeningTime = knownAvgAwakeningUpTime;
- }
- AvgAwakeningTimeUs = Ts2Us(avgAwakeningTime);
-
- ui64 avgWakingUpConsumption = avgWakingUpTime + avgAwakeningTime;
- LWPROBE(WakingUpConsumption, Ts2Us(avgWakingUpTime), Ts2Us(avgWakingUpTime), Ts2Us(avgAwakeningTime), Ts2Us(realAvgAwakeningTime), Ts2Us(avgWakingUpConsumption));
-
- for (size_t poolIdx = 0; poolIdx < Pools.size(); ++poolIdx) {
- TPoolInfo& pool = Pools[poolIdx];
- if (!pool.BasicPool) {
- continue;
- }
- if constexpr (NFeatures::TSpinFeatureFlags::CalcPerThread) {
- pool.BasicPool->CalcSpinPerThread(avgWakingUpConsumption);
- } else if constexpr (NFeatures::TSpinFeatureFlags::UsePseudoMovingWindow) {
- ui64 newSpinThreshold = pool.MovingWaitingStats->CalculateGoodSpinThresholdCycles(avgWakingUpConsumption);
- pool.BasicPool->SetSpinThresholdCycles(newSpinThreshold);
- } else {
- ui64 newSpinThreshold = pool.WaitingStats->CalculateGoodSpinThresholdCycles(avgWakingUpConsumption);
- pool.BasicPool->SetSpinThresholdCycles(newSpinThreshold);
- }
- pool.BasicPool->ClearWaitingStats();
- }
-
- for (size_t poolIdx = 0; poolIdx < Pools.size(); ++poolIdx) {
- TPoolInfo& pool = Pools[poolIdx];
- total += pool.DefaultThreadCount;
-
- ui32 currentThreadCount = pool.GetThreadCount();
- sumOfAdditionalThreads += currentThreadCount - pool.DefaultThreadCount;
-
- double poolBooked = 0.0;
- double poolConsumed = 0.0;
- double lastSecondPoolBooked = 0.0;
- double lastSecondPoolConsumed = 0.0;
- beingStopped += pool.Pool->GetBlockingThreadCount();
- for (i16 threadIdx = 0; threadIdx < pool.MaxThreadCount; ++threadIdx) {
- poolBooked += Rescale(pool.GetBooked(threadIdx));
- lastSecondPoolBooked += Rescale(pool.GetlastSecondPoolBooked(threadIdx));
- poolConsumed += Rescale(pool.GetConsumed(threadIdx));
- lastSecondPoolConsumed += Rescale(pool.GetlastSecondPoolConsumed(threadIdx));
- }
- bool isStarved = IsStarved(poolConsumed, poolBooked) || IsStarved(lastSecondPoolConsumed, lastSecondPoolBooked);
- if (isStarved) {
- isStarvedPresent = true;
- }
-
- bool isNeedy = (pool.IsAvgPingGood() || pool.NewNotEnoughCpuExecutions) && poolBooked >= currentThreadCount;
- if (pool.AvgPingCounter) {
- if (pool.LastUpdateTs + Us2Ts(3'000'000ull) > ts) {
- isNeedy = false;
- } else {
- pool.LastUpdateTs = ts;
- }
- }
- isNeedyByPool.push_back(isNeedy);
- if (isNeedy) {
- needyPools.push_back(poolIdx);
- }
- bool isHoggish = IsHoggish(poolBooked, currentThreadCount)
- || IsHoggish(lastSecondPoolBooked, currentThreadCount);
- if (isHoggish) {
- hoggishPools.push_back(poolIdx);
- }
- booked += poolBooked;
- consumed += poolConsumed;
- AtomicSet(pool.LastFlags, (i64)isNeedy | ((i64)isStarved << 1) | ((i64)isHoggish << 2));
- LWPROBE(HarmonizeCheckPool, poolIdx, pool.Pool->GetName(), poolBooked, poolConsumed, lastSecondPoolBooked, lastSecondPoolConsumed, pool.GetThreadCount(), pool.MaxThreadCount, isStarved, isNeedy, isHoggish);
- }
- double budget = total - Max(booked, lastSecondBooked);
- i16 budgetInt = static_cast<i16>(Max(budget, 0.0));
- if (budget < -0.1) {
- isStarvedPresent = true;
- }
- for (size_t poolIdx = 0; poolIdx < Pools.size(); ++poolIdx) {
- TPoolInfo& pool = Pools[poolIdx];
- AtomicSet(pool.PotentialMaxThreadCount, Min(pool.MaxThreadCount, budgetInt));
- }
- double overbooked = consumed - booked;
- if (overbooked < 0) {
- isStarvedPresent = false;
- }
-
- if (needyPools.size()) {
- Sort(needyPools.begin(), needyPools.end(), [&] (i16 lhs, i16 rhs) {
- if (Pools[lhs].Priority != Pools[rhs].Priority) {
- return Pools[lhs].Priority > Pools[rhs].Priority;
- }
- return Pools[lhs].Pool->PoolId < Pools[rhs].Pool->PoolId;
- });
- }
-
- if (isStarvedPresent) {
- // last_starved_at_consumed_value = сумма по всем пулам consumed;
- // TODO(cthulhu): использовать как лимит планвно устремлять этот лимит к total,
- // использовать вместо total
- if (beingStopped && beingStopped >= overbooked) {
- // do nothing
- } else {
- for (ui16 poolIdx : PriorityOrder) {
- TPoolInfo &pool = Pools[poolIdx];
- i64 threadCount = pool.GetThreadCount();
- while (threadCount > pool.DefaultThreadCount) {
- pool.SetThreadCount(--threadCount);
- AtomicIncrement(pool.DecreasingThreadsByStarvedState);
- overbooked--;
- sumOfAdditionalThreads--;
-
- LWPROBE(HarmonizeOperation, poolIdx, pool.Pool->GetName(), "decrease by starving", threadCount - 1, pool.DefaultThreadCount, pool.MaxThreadCount);
- if (overbooked < 1) {
- break;
- }
- }
- if (overbooked < 1) {
- break;
- }
- }
- }
- } else {
- for (size_t needyPoolIdx : needyPools) {
- TPoolInfo &pool = Pools[needyPoolIdx];
- i64 threadCount = pool.GetThreadCount();
- if (budget >= 1.0) {
- if (threadCount + 1 <= pool.MaxThreadCount) {
- AtomicIncrement(pool.IncreasingThreadsByNeedyState);
- isNeedyByPool[needyPoolIdx] = false;
- sumOfAdditionalThreads++;
- pool.SetThreadCount(threadCount + 1);
- budget -= 1.0;
- LWPROBE(HarmonizeOperation, needyPoolIdx, pool.Pool->GetName(), "increase by needs", threadCount + 1, pool.DefaultThreadCount, pool.MaxThreadCount);
- }
- }
- if constexpr (NFeatures::IsLocalQueues()) {
- bool needToExpandLocalQueue = budget < 1.0 || threadCount >= pool.MaxThreadCount;
- needToExpandLocalQueue &= (bool)pool.BasicPool;
- needToExpandLocalQueue &= (pool.MaxThreadCount > 1);
- needToExpandLocalQueue &= (pool.LocalQueueSize < NFeatures::TLocalQueuesFeatureFlags::MAX_LOCAL_QUEUE_SIZE);
- if (needToExpandLocalQueue) {
- pool.BasicPool->SetLocalQueueSize(++pool.LocalQueueSize);
- }
- }
- }
- }
-
- if (budget < 1.0) {
- size_t takingAwayThreads = 0;
- for (size_t needyPoolIdx : needyPools) {
- TPoolInfo &pool = Pools[needyPoolIdx];
- i64 threadCount = pool.GetThreadCount();
- sumOfAdditionalThreads -= threadCount - pool.DefaultThreadCount;
- if (sumOfAdditionalThreads < takingAwayThreads + 1) {
- break;
- }
- if (!isNeedyByPool[needyPoolIdx]) {
- continue;
- }
- AtomicIncrement(pool.IncreasingThreadsByExchange);
- isNeedyByPool[needyPoolIdx] = false;
- takingAwayThreads++;
- pool.SetThreadCount(threadCount + 1);
-
- LWPROBE(HarmonizeOperation, needyPoolIdx, pool.Pool->GetName(), "increase by exchanging", threadCount + 1, pool.DefaultThreadCount, pool.MaxThreadCount);
- }
-
- for (ui16 poolIdx : PriorityOrder) {
- if (takingAwayThreads <= 0) {
- break;
- }
-
- TPoolInfo &pool = Pools[poolIdx];
- size_t threadCount = pool.GetThreadCount();
- size_t additionalThreadsCount = Max<size_t>(0L, threadCount - pool.DefaultThreadCount);
- size_t currentTakingAwayThreads = Min(additionalThreadsCount, takingAwayThreads);
-
- if (!currentTakingAwayThreads) {
- continue;
- }
- takingAwayThreads -= currentTakingAwayThreads;
- pool.SetThreadCount(threadCount - currentTakingAwayThreads);
-
- AtomicAdd(pool.DecreasingThreadsByExchange, takingAwayThreads);
- LWPROBE(HarmonizeOperation, poolIdx, pool.Pool->GetName(), "decrease by exchanging", threadCount - currentTakingAwayThreads, pool.DefaultThreadCount, pool.MaxThreadCount);
- }
- }
-
- for (size_t hoggishPoolIdx : hoggishPools) {
- TPoolInfo &pool = Pools[hoggishPoolIdx];
- i64 threadCount = pool.GetThreadCount();
- if (pool.BasicPool && pool.LocalQueueSize > NFeatures::TLocalQueuesFeatureFlags::MIN_LOCAL_QUEUE_SIZE) {
- pool.LocalQueueSize = std::min<ui16>(NFeatures::TLocalQueuesFeatureFlags::MIN_LOCAL_QUEUE_SIZE, pool.LocalQueueSize / 2);
- pool.BasicPool->SetLocalQueueSize(pool.LocalQueueSize);
- }
- if (threadCount > pool.MinThreadCount) {
- AtomicIncrement(pool.DecreasingThreadsByHoggishState);
- LWPROBE(HarmonizeOperation, hoggishPoolIdx, pool.Pool->GetName(), "decrease by hoggish", threadCount - 1, pool.DefaultThreadCount, pool.MaxThreadCount);
- pool.SetThreadCount(threadCount - 1);
- }
- }
-}
-
-void THarmonizer::CalculatePriorityOrder() {
- PriorityOrder.resize(Pools.size());
- Iota(PriorityOrder.begin(), PriorityOrder.end(), 0);
- Sort(PriorityOrder.begin(), PriorityOrder.end(), [&] (i16 lhs, i16 rhs) {
- if (Pools[lhs].Priority != Pools[rhs].Priority) {
- return Pools[lhs].Priority < Pools[rhs].Priority;
- }
- return Pools[lhs].Pool->PoolId > Pools[rhs].Pool->PoolId;
- });
-}
-
-void THarmonizer::Harmonize(ui64 ts) {
- if (IsDisabled || NextHarmonizeTs > ts || !Lock.TryAcquire()) {
- LWPROBE(TryToHarmonizeFailed, ts, NextHarmonizeTs, IsDisabled, false);
- return;
- }
- // Check again under the lock
- if (IsDisabled) {
- LWPROBE(TryToHarmonizeFailed, ts, NextHarmonizeTs, IsDisabled, true);
- Lock.Release();
- return;
- }
- // Will never reach this line disabled
- ui64 previousNextHarmonizeTs = NextHarmonizeTs.exchange(ts + Us2Ts(1'000'000ull));
- LWPROBE(TryToHarmonizeSuccess, ts, NextHarmonizeTs, previousNextHarmonizeTs);
-
- if (PriorityOrder.empty()) {
- CalculatePriorityOrder();
- }
-
- PullStats(ts);
- HarmonizeImpl(ts);
-
- Lock.Release();
-}
-
-void THarmonizer::DeclareEmergency(ui64 ts) {
- NextHarmonizeTs = ts;
-}
-
-void THarmonizer::AddPool(IExecutorPool* pool, TSelfPingInfo *pingInfo) {
- TGuard<TSpinLock> guard(Lock);
- TPoolInfo poolInfo;
- poolInfo.Pool = pool;
- poolInfo.BasicPool = dynamic_cast<TBasicExecutorPool*>(pool);
- poolInfo.DefaultThreadCount = pool->GetDefaultThreadCount();
- poolInfo.MinThreadCount = pool->GetMinThreadCount();
- poolInfo.MaxThreadCount = pool->GetMaxThreadCount();
- poolInfo.ThreadInfo.resize(poolInfo.MaxThreadCount);
- poolInfo.Priority = pool->GetPriority();
- pool->SetThreadCount(poolInfo.DefaultThreadCount);
- if (pingInfo) {
- poolInfo.AvgPingCounter = pingInfo->AvgPingCounter;
- poolInfo.AvgPingCounterWithSmallWindow = pingInfo->AvgPingCounterWithSmallWindow;
- poolInfo.MaxAvgPingUs = pingInfo->MaxAvgPingUs;
- }
- if (poolInfo.BasicPool) {
- poolInfo.WaitingStats.reset(new TWaitingStats<ui64>());
- poolInfo.MovingWaitingStats.reset(new TWaitingStats<double>());
- }
- Pools.push_back(std::move(poolInfo));
- PriorityOrder.clear();
-}
-
-void THarmonizer::Enable(bool enable) {
- TGuard<TSpinLock> guard(Lock);
- IsDisabled = enable;
-}
-
-IHarmonizer* MakeHarmonizer(ui64 ts) {
- return new THarmonizer(ts);
-}
-
-TPoolHarmonizerStats THarmonizer::GetPoolStats(i16 poolId) const {
- const TPoolInfo &pool = Pools[poolId];
- ui64 flags = RelaxedLoad(&pool.LastFlags);
- return TPoolHarmonizerStats{
- .IncreasingThreadsByNeedyState = static_cast<ui64>(RelaxedLoad(&pool.IncreasingThreadsByNeedyState)),
- .IncreasingThreadsByExchange = static_cast<ui64>(RelaxedLoad(&pool.IncreasingThreadsByExchange)),
- .DecreasingThreadsByStarvedState = static_cast<ui64>(RelaxedLoad(&pool.DecreasingThreadsByStarvedState)),
- .DecreasingThreadsByHoggishState = static_cast<ui64>(RelaxedLoad(&pool.DecreasingThreadsByHoggishState)),
- .DecreasingThreadsByExchange = static_cast<ui64>(RelaxedLoad(&pool.DecreasingThreadsByExchange)),
- .MaxConsumedCpu = static_cast<i64>(RelaxedLoad(&pool.MaxConsumedCpu)),
- .MinConsumedCpu = static_cast<i64>(RelaxedLoad(&pool.MinConsumedCpu)),
- .MaxBookedCpu = static_cast<i64>(RelaxedLoad(&pool.MaxBookedCpu)),
- .MinBookedCpu = static_cast<i64>(RelaxedLoad(&pool.MinBookedCpu)),
- .PotentialMaxThreadCount = static_cast<i16>(RelaxedLoad(&pool.PotentialMaxThreadCount)),
- .IsNeedy = static_cast<bool>(flags & 1),
- .IsStarved = static_cast<bool>(flags & 2),
- .IsHoggish = static_cast<bool>(flags & 4),
- };
-}
-
-THarmonizerStats THarmonizer::GetStats() const {
- return THarmonizerStats{
- .MaxConsumedCpu = static_cast<i64>(RelaxedLoad(&MaxConsumedCpu)),
- .MinConsumedCpu = static_cast<i64>(RelaxedLoad(&MinConsumedCpu)),
- .MaxBookedCpu = static_cast<i64>(RelaxedLoad(&MaxBookedCpu)),
- .MinBookedCpu = static_cast<i64>(RelaxedLoad(&MinBookedCpu)),
- .AvgAwakeningTimeUs = AvgAwakeningTimeUs,
- .AvgWakingUpTimeUs = AvgWakingUpTimeUs,
- };
-}
-
-}
diff --git a/library/cpp/actors/core/harmonizer.h b/library/cpp/actors/core/harmonizer.h
deleted file mode 100644
index ba98048e49..0000000000
--- a/library/cpp/actors/core/harmonizer.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include "config.h"
-
-namespace NActors {
- class IExecutorPool;
-
- template <typename T>
- struct TWaitingStats;
-
- struct TPoolHarmonizerStats {
- ui64 IncreasingThreadsByNeedyState = 0;
- ui64 IncreasingThreadsByExchange = 0;
- ui64 DecreasingThreadsByStarvedState = 0;
- ui64 DecreasingThreadsByHoggishState = 0;
- ui64 DecreasingThreadsByExchange = 0;
- i64 MaxConsumedCpu = 0.0;
- i64 MinConsumedCpu = 0.0;
- i64 MaxBookedCpu = 0.0;
- i64 MinBookedCpu = 0.0;
- i16 PotentialMaxThreadCount = 0;
- bool IsNeedy = false;
- bool IsStarved = false;
- bool IsHoggish = false;
- };
-
- struct THarmonizerStats {
- i64 MaxConsumedCpu = 0.0;
- i64 MinConsumedCpu = 0.0;
- i64 MaxBookedCpu = 0.0;
- i64 MinBookedCpu = 0.0;
-
- double AvgAwakeningTimeUs = 0;
- double AvgWakingUpTimeUs = 0;
- };
-
- // Pool cpu harmonizer
- class IHarmonizer {
- public:
- virtual ~IHarmonizer() {}
- virtual void Harmonize(ui64 ts) = 0;
- virtual void DeclareEmergency(ui64 ts) = 0;
- virtual void AddPool(IExecutorPool* pool, TSelfPingInfo *pingInfo = nullptr) = 0;
- virtual void Enable(bool enable) = 0;
- virtual TPoolHarmonizerStats GetPoolStats(i16 poolId) const = 0;
- virtual THarmonizerStats GetStats() const = 0;
- };
-
- IHarmonizer* MakeHarmonizer(ui64 ts);
-}
diff --git a/library/cpp/actors/core/hfunc.h b/library/cpp/actors/core/hfunc.h
deleted file mode 100644
index 6d1aeeecc3..0000000000
--- a/library/cpp/actors/core/hfunc.h
+++ /dev/null
@@ -1,116 +0,0 @@
-#pragma once
-
-#include "actor.h"
-#include "executor_thread.h"
-
-#include <util/system/defaults.h>
-
-#define HFuncCtx(TEvType, HandleFunc, Ctx) \
- case TEvType::EventType: { \
- typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \
- HandleFunc(*x, Ctx); \
- break; \
- }
-
-#define HFunc(TEvType, HandleFunc) \
- case TEvType::EventType: { \
- typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \
- HandleFunc(*x, this->ActorContext()); \
- break; \
- }
-
-#define hFunc(TEvType, HandleFunc) \
- case TEvType::EventType: { \
- typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \
- HandleFunc(*x); \
- break; \
- }
-
-#define HFuncTraced(TEvType, HandleFunc) \
- case TEvType::EventType: { \
- TRACE_EVENT_TYPE(Y_STRINGIZE(TEvType)); \
- TEvType::TPtr* x = reinterpret_cast<TEvType::TPtr*>(&ev); \
- HandleFunc(*x, this->ActorContext()); \
- break; \
- }
-
-#define hFuncTraced(TEvType, HandleFunc) \
- case TEvType::EventType: { \
- TRACE_EVENT_TYPE(Y_STRINGIZE(TEvType)); \
- typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \
- HandleFunc(*x); \
- break; \
- }
-
-#define HTemplFunc(TEvType, HandleFunc) \
- case TEvType::EventType: { \
- typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \
- HandleFunc(*x, this->ActorContext()); \
- break; \
- }
-
-#define hTemplFunc(TEvType, HandleFunc) \
- case TEvType::EventType: { \
- typename TEvType::TPtr* x = reinterpret_cast<typename TEvType::TPtr*>(&ev); \
- HandleFunc(*x); \
- break; \
- }
-
-#define SFunc(TEvType, HandleFunc) \
- case TEvType::EventType: \
- HandleFunc(this->ActorContext()); \
- break;
-
-#define sFunc(TEvType, HandleFunc) \
- case TEvType::EventType: \
- HandleFunc(); \
- break;
-
-#define CFunc(TEventType, HandleFunc) \
- case TEventType: \
- HandleFunc(this->ActorContext()); \
- break;
-
-#define CFuncCtx(TEventType, HandleFunc, ctx) \
- case TEventType: \
- HandleFunc(ctx); \
- break;
-
-#define cFunc(TEventType, HandleFunc) \
- case TEventType: \
- HandleFunc(); \
- break;
-
-#define FFunc(TEventType, HandleFunc) \
- case TEventType: \
- HandleFunc(ev, this->ActorContext()); \
- break;
-
-#define fFunc(TEventType, HandleFunc) \
- case TEventType: \
- HandleFunc(ev); \
- break;
-
-#define IgnoreFunc(TEvType) \
- case TEvType::EventType: \
- break;
-
-#define ExceptionFunc(ExceptionType, HandleFunc) \
- catch (const ExceptionType& exception) { \
- HandleFunc(exception); \
- }
-
-#define ExceptionFuncEv(ExceptionType, HandleFunc) \
- catch (const ExceptionType& exception) { \
- HandleFunc(exception, ev); \
- }
-
-#define AnyExceptionFunc(HandleFunc) \
- catch (...) { \
- HandleFunc(); \
- }
-
-#define AnyExceptionFuncEv(HandleFunc) \
- catch (...) { \
- HandleFunc(ev); \
- }
diff --git a/library/cpp/actors/core/interconnect.cpp b/library/cpp/actors/core/interconnect.cpp
deleted file mode 100644
index b477f71e57..0000000000
--- a/library/cpp/actors/core/interconnect.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-#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_ABORT_UNLESS(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_ABORT_UNLESS(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))
- {}
-
- TNodeLocation::TNodeLocation(const TString& DataCenter, const TString& Module, const TString& Rack, const TString& Unit) {
- if (DataCenter) Items.emplace_back(TKeys::DataCenter, DataCenter);
- if (Module) Items.emplace_back(TKeys::Module, Module);
- if (Rack) Items.emplace_back(TKeys::Rack, Rack);
- if (Unit) Items.emplace_back(TKeys::Unit, Unit);
- }
-
- NActorsInterconnect::TNodeLocation TNodeLocation::ParseLocation(const TString& s) {
- NActorsInterconnect::TNodeLocation res;
- const bool success = res.ParseFromString(s);
- Y_ABORT_UNLESS(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, bool compatibleWithOlderVersions) 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);
- }
- }
- if (compatibleWithOlderVersions) {
- GetLegacyValue().Serialize(pb);
- }
- }
-
- TString TNodeLocation::GetSerializedLocation() const {
- NActorsInterconnect::TNodeLocation pb;
- Serialize(&pb, false);
- TString s;
- const bool success = pb.SerializeToString(&s);
- Y_ABORT_UNLESS(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_ABORT_UNLESS(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_ABORT_UNLESS(success);
- break;
- }
-
- default:
- Y_ABORT("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
deleted file mode 100644
index 46d4fd5303..0000000000
--- a/library/cpp/actors/core/interconnect.h
+++ /dev/null
@@ -1,268 +0,0 @@
-#pragma once
-
-#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>
-
-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;
-
- public:
- // generic ctors
- TNodeLocation() = default;
- TNodeLocation(const TNodeLocation&) = default;
- TNodeLocation(TNodeLocation&&) = default;
- TNodeLocation(const TString& DataCenter, const TString& Module = "", const TString& Rack = "", const TString& Unit = "");
-
- // 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;
-
- // compatibleWithOlderVersions should be set to true when this protobuf is possibly going to be delivered to 21-4
- void Serialize(NActorsInterconnect::TNodeLocation *pb, bool compatibleWithOlderVersions) 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 GetUnitId() const { return ToStringUpTo(TKeys::Unit); }
- 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 {
- enum EEv {
- EvForward = EventSpaceBegin(TEvents::ES_INTERCONNECT),
- EvResolveNode, // resolve info about node (internal)
- EvNodeAddress, // node info (internal)
- EvConnectNode, // request proxy to establish connection (like: we would send something there soon)
- EvAcceptIncoming,
- EvNodeConnected, // node connected notify
- EvNodeDisconnected, // node disconnected notify
- EvRegisterNode,
- EvRegisterNodeResult,
- EvListNodes,
- EvNodesInfo,
- EvDisconnect,
- EvGetNode,
- EvNodeInfo,
- EvClosePeerSocket,
- EvCloseInputSession,
- EvPoisonSession,
- EvTerminate,
- EvEnd
- };
-
- enum ESubscribes {
- SubConnected,
- SubDisconnected,
- };
-
- static_assert(EvEnd < EventSpaceEnd(TEvents::ES_INTERCONNECT), "expect EvEnd < EventSpaceEnd(TEvents::ES_INTERCONNECT)");
-
- struct TEvResolveNode;
- struct TEvNodeAddress;
-
- struct TEvConnectNode: public TEventBase<TEvConnectNode, EvConnectNode> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvConnectNode, "TEvInterconnect::TEvConnectNode")
- };
-
- struct TEvAcceptIncoming;
-
- struct TEvNodeConnected: public TEventLocal<TEvNodeConnected, EvNodeConnected> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvNodeConnected, "TEvInterconnect::TEvNodeConnected")
- TEvNodeConnected(ui32 node) noexcept
- : NodeId(node)
- {
- }
- const ui32 NodeId;
- };
-
- struct TEvNodeDisconnected: public TEventLocal<TEvNodeDisconnected, EvNodeDisconnected> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvNodeDisconnected, "TEvInterconnect::TEvNodeDisconnected")
- TEvNodeDisconnected(ui32 node) noexcept
- : NodeId(node)
- {
- }
- const ui32 NodeId;
- };
-
- struct TEvRegisterNode;
- struct TEvRegisterNodeResult;
-
- struct TEvListNodes: public TEventLocal<TEvListNodes, EvListNodes> {
- const bool SubscribeToStaticNodeChanges = false;
-
- TEvListNodes() = default;
-
- TEvListNodes(bool subscribeToStaticNodeChanges)
- : SubscribeToStaticNodeChanges(subscribeToStaticNodeChanges)
- {}
- };
-
- struct TNodeInfo {
- ui32 NodeId;
- TString Address;
- TString Host;
- TString ResolveHost;
- ui16 Port;
- TNodeLocation Location;
- bool IsStatic = true;
-
- TNodeInfo() = default;
- TNodeInfo(const TNodeInfo&) = default;
- TNodeInfo& operator =(const TNodeInfo&) = default;
- TNodeInfo(ui32 nodeId,
- const TString& address,
- const TString& host,
- const TString& resolveHost,
- ui16 port,
- const TNodeLocation& location,
- bool isStatic = true)
- : NodeId(nodeId)
- , Address(address)
- , Host(host)
- , ResolveHost(resolveHost)
- , Port(port)
- , Location(location)
- , IsStatic(isStatic)
- {
- }
-
- operator ui32() const {
- return NodeId;
- }
- };
-
- struct TEvNodesInfo: public TEventLocal<TEvNodesInfo, EvNodesInfo> {
- TVector<TNodeInfo> Nodes;
-
- const TNodeInfo* GetNodeInfo(ui32 nodeId) const {
- for (const auto& x : Nodes) {
- if (x.NodeId == nodeId)
- return &x;
- }
- return nullptr;
- }
- };
-
- struct TEvDisconnect;
-
- struct TEvGetNode: public TEventLocal<TEvGetNode, EvGetNode> {
- ui32 NodeId;
- TInstant Deadline;
-
- TEvGetNode(ui32 nodeId, TInstant deadline = TInstant::Max())
- : NodeId(nodeId)
- , Deadline(deadline)
- {
- }
- };
-
- struct TEvNodeInfo: public TEventLocal<TEvNodeInfo, EvNodeInfo> {
- TEvNodeInfo(ui32 nodeId)
- : NodeId(nodeId)
- {
- }
-
- 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> {};
- };
-}
diff --git a/library/cpp/actors/core/invoke.h b/library/cpp/actors/core/invoke.h
deleted file mode 100644
index c9e29effe2..0000000000
--- a/library/cpp/actors/core/invoke.h
+++ /dev/null
@@ -1,145 +0,0 @@
-#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_ABORT_UNLESS(!arg.has_value());
- } else if (auto *value = std::any_cast<T>(&arg)) {
- return std::move(*value);
- } else {
- Y_ABORT("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.
-
- template<typename TCallback, typename TCompletion, class TEnum>
- class TInvokeActor : public TActorBootstrapped<TInvokeActor<TCallback, TCompletion, TEnum>> {
- private:
- using TBase = TActorBootstrapped<TInvokeActor<TCallback, TCompletion, TEnum>>;
- TCallback Callback;
- TCompletion Complete;
- const TEnum Activity;
- static_assert(std::is_enum<TEnum>::value);
- public:
- TInvokeActor(TCallback&& callback, TCompletion&& complete, const TEnum activity)
- : TBase(activity)
- , Callback(std::move(callback))
- , Complete(std::move(complete))
- , Activity(activity)
- {}
-
- 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);
- }
- };
-
- template<typename TEnum, typename TCallback, typename TCompletion>
- std::unique_ptr<IActor> CreateInvokeActor(TCallback&& callback, TCompletion&& complete, const TEnum activity) {
- return std::make_unique<TInvokeActor<std::decay_t<TCallback>, std::decay_t<TCompletion>, TEnum>>(
- std::forward<TCallback>(callback), std::forward<TCompletion>(complete), activity);
- }
-
- template <class TInvokeExecutor>
- class TScheduledInvokeActivity: public TActor<TScheduledInvokeActivity<TInvokeExecutor>> {
- private:
- using TBase = TActor<TScheduledInvokeActivity<TInvokeExecutor>>;
- const TMonotonic Timestamp;
- TInvokeExecutor Executor;
- public:
- TScheduledInvokeActivity(TInvokeExecutor&& executor, const TMonotonic timestamp)
- : TBase(&TBase::TThis::StateFunc)
- , Timestamp(timestamp)
- , Executor(std::move(executor)) {
- }
-
- void StateFunc(STFUNC_SIG) {
- Y_ABORT_UNLESS(ev->GetTypeRewrite() == TEvents::TSystem::Wakeup);
- auto g = TBase::PassAwayGuard();
- Executor();
- }
-
- void Registered(TActorSystem* sys, const TActorId& owner) override {
- sys->Schedule(Timestamp, new IEventHandle(TEvents::TSystem::Wakeup, 0, TBase::SelfId(), owner, nullptr, 0));
- }
- };
-
- template<class TInvokeExecutor>
- void ScheduleInvokeActivity(TInvokeExecutor&& executor, const TDuration d) {
- TActivationContext::Register(new TScheduledInvokeActivity<TInvokeExecutor>(std::move(executor), TMonotonic::Now() + d));
- }
-
- template<class TInvokeExecutor>
- void ScheduleInvokeActivity(TInvokeExecutor&& executor, const TMonotonic timestamp) {
- TActivationContext::Register(new TScheduledInvokeActivity<TInvokeExecutor>(std::move(executor), timestamp));
- }
-
-} // NActors
diff --git a/library/cpp/actors/core/io_dispatcher.cpp b/library/cpp/actors/core/io_dispatcher.cpp
deleted file mode 100644
index c7d28c63e0..0000000000
--- a/library/cpp/actors/core/io_dispatcher.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-#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_ABORT_UNLESS(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_ABORT_UNLESS(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();
- }
-
- static constexpr char ActorName[] = "IO_DISPATCHER_ACTOR";
-
- void Bootstrap() {
- while (NumRunningThreads < MinThreadCount) {
- StartThread();
- }
- HandleWakeup();
- Become(&TThis::StateFunc);
- }
-
- void HandleThreadStopped(TAutoPtr<IEventHandle> ev) {
- auto it = Threads.find(ev->Cookie);
- Y_ABORT_UNLESS(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
deleted file mode 100644
index b0e4e60d1a..0000000000
--- a/library/cpp/actors/core/io_dispatcher.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#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/lease.h b/library/cpp/actors/core/lease.h
deleted file mode 100644
index 650ae7b122..0000000000
--- a/library/cpp/actors/core/lease.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NActors {
- // Value representing specific worker's permission for exclusive use of CPU till specific deadline
- struct TLease {
- // Lower WorkerBits store current fast worker id
- // All other higher bits store expiration (hard preemption) timestamp
- using TValue = ui64;
- TValue Value;
-
- static constexpr ui64 WorkerIdMask = ui64((1ull << WorkerBits) - 1);
- static constexpr ui64 ExpireTsMask = ~WorkerIdMask;
-
- explicit constexpr TLease(ui64 value)
- : Value(value)
- {}
-
- constexpr TLease(TWorkerId workerId, ui64 expireTs)
- : Value((workerId & WorkerIdMask) | (expireTs & ExpireTsMask))
- {}
-
- TWorkerId GetWorkerId() const {
- return Value & WorkerIdMask;
- }
-
- TLease NeverExpire() const {
- return TLease(Value | ExpireTsMask);
- }
-
- bool IsNeverExpiring() const {
- return (Value & ExpireTsMask) == ExpireTsMask;
- }
-
- ui64 GetExpireTs() const {
- // Do not truncate worker id
- // NOTE: it decrease accuracy, but improves performance
- return Value;
- }
-
- ui64 GetPreciseExpireTs() const {
- return Value & ExpireTsMask;
- }
-
- operator TValue() const {
- return Value;
- }
- };
-
- // Special expire timestamp values
- static constexpr ui64 NeverExpire = ui64(-1);
-
- // Special hard-preemption-in-progress lease
- static constexpr TLease HardPreemptionLease = TLease(TLease::WorkerIdMask, NeverExpire);
-}
diff --git a/library/cpp/actors/core/log.cpp b/library/cpp/actors/core/log.cpp
deleted file mode 100644
index 1a8880d15d..0000000000
--- a/library/cpp/actors/core/log.cpp
+++ /dev/null
@@ -1,768 +0,0 @@
-#include "log.h"
-
-static_assert(int(NActors::NLog::PRI_EMERG) == int(::TLOG_EMERG), "expect int(NActors::NLog::PRI_EMERG) == int(::TLOG_EMERG)");
-static_assert(int(NActors::NLog::PRI_ALERT) == int(::TLOG_ALERT), "expect int(NActors::NLog::PRI_ALERT) == int(::TLOG_ALERT)");
-static_assert(int(NActors::NLog::PRI_CRIT) == int(::TLOG_CRIT), "expect int(NActors::NLog::PRI_CRIT) == int(::TLOG_CRIT)");
-static_assert(int(NActors::NLog::PRI_ERROR) == int(::TLOG_ERR), "expect int(NActors::NLog::PRI_ERROR) == int(::TLOG_ERR)");
-static_assert(int(NActors::NLog::PRI_WARN) == int(::TLOG_WARNING), "expect int(NActors::NLog::PRI_WARN) == int(::TLOG_WARNING)");
-static_assert(int(NActors::NLog::PRI_NOTICE) == int(::TLOG_NOTICE), "expect int(NActors::NLog::PRI_NOTICE) == int(::TLOG_NOTICE)");
-static_assert(int(NActors::NLog::PRI_INFO) == int(::TLOG_INFO), "expect int(NActors::NLog::PRI_INFO) == int(::TLOG_INFO)");
-static_assert(int(NActors::NLog::PRI_DEBUG) == int(::TLOG_DEBUG), "expect int(NActors::NLog::PRI_DEBUG) == int(::TLOG_DEBUG)");
-static_assert(int(NActors::NLog::PRI_TRACE) == int(::TLOG_RESOURCES), "expect int(NActors::NLog::PRI_TRACE) == int(::TLOG_RESOURCES)");
-
-namespace {
- struct TRecordWithNewline {
- ELogPriority Priority;
- TTempBuf Buf;
-
- TRecordWithNewline(const TLogRecord& rec)
- : Priority(rec.Priority)
- , Buf(rec.Len + 1)
- {
- Buf.Append(rec.Data, rec.Len);
- *Buf.Proceed(1) = '\n';
- }
-
- operator TLogRecord() const {
- return TLogRecord(Priority, Buf.Data(), Buf.Filled());
- }
- };
-}
-
-namespace NActors {
- TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- TAutoPtr<TLogBackend> logBackend,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters)
- : TActor(&TLoggerActor::StateFunc)
- , Settings(settings)
- , LogBackend(logBackend.Release())
- , Metrics(std::make_unique<TLoggerCounters>(counters))
- , LogBuffer(*Metrics, *Settings)
- {
- }
-
- TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- std::shared_ptr<TLogBackend> logBackend,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters)
- : TActor(&TLoggerActor::StateFunc)
- , Settings(settings)
- , LogBackend(logBackend)
- , Metrics(std::make_unique<TLoggerCounters>(counters))
- , LogBuffer(*Metrics, *Settings)
- {
- }
-
- TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- TAutoPtr<TLogBackend> logBackend,
- std::shared_ptr<NMonitoring::TMetricRegistry> metrics)
- : TActor(&TLoggerActor::StateFunc)
- , Settings(settings)
- , LogBackend(logBackend.Release())
- , Metrics(std::make_unique<TLoggerMetrics>(metrics))
- , LogBuffer(*Metrics, *Settings)
- {
- }
-
- TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- std::shared_ptr<TLogBackend> logBackend,
- std::shared_ptr<NMonitoring::TMetricRegistry> metrics)
- : TActor(&TLoggerActor::StateFunc)
- , Settings(settings)
- , LogBackend(logBackend)
- , Metrics(std::make_unique<TLoggerMetrics>(metrics))
- , LogBuffer(*Metrics, *Settings)
- {
- }
-
- TLoggerActor::~TLoggerActor() {
- }
-
- void TLoggerActor::Log(TInstant time, NLog::EPriority priority, NLog::EComponent component, const char* c, ...) {
- Metrics->IncDirectMsgs();
- if (Settings && Settings->Satisfies(priority, component, 0ull)) {
- va_list params;
- va_start(params, c);
- TString formatted;
- vsprintf(formatted, c, params);
-
- auto ok = OutputRecord(time, NLog::EPrio(priority), component, formatted);
- Y_UNUSED(ok);
- va_end(params);
- }
- }
-
- void TLoggerActor::Throttle(const NLog::TSettings& settings) {
- // throttling via Sleep was removed since it causes unexpected
- // incidents when users try to set AllowDrop=false.
- Y_UNUSED(settings);
- }
-
- void TLoggerActor::FlushLogBufferMessage() {
- if (!LogBuffer.IsEmpty()) {
- NLog::TEvLog *log = LogBuffer.Pop();
- if (!OutputRecord(log)) {
- BecomeDefunct();
- }
- delete log;
- }
- }
-
- void TLoggerActor::FlushLogBufferMessageEvent(TFlushLogBuffer::TPtr& ev, const NActors::TActorContext& ctx) {
- Y_UNUSED(ev);
- FlushLogBufferMessage();
-
- ui64 ignoredCount = LogBuffer.GetIgnoredCount();
- if (ignoredCount > 0) {
- NLog::EPrio prio = LogBuffer.GetIgnoredHighestPrio();
- TString message = Sprintf("Logger overflow! Ignored %" PRIu64 " log records with priority [%s] or lower!", ignoredCount, PriorityToString(prio));
- if (!OutputRecord(ctx.Now(), NActors::NLog::EPrio::Error, Settings->LoggerComponent, message)) {
- BecomeDefunct();
- }
- LogBuffer.ClearIgnoredCount();
- }
-
- if (!LogBuffer.IsEmpty()) {
- ctx.Send(ctx.SelfID, ev->Release().Release());
- }
- }
-
- void TLoggerActor::WriteMessageStat(const NLog::TEvLog& ev) {
- Metrics->IncActorMsgs();
-
- const auto prio = ev.Level.ToPrio();
-
- switch (prio) {
- case ::NActors::NLog::EPrio::Alert:
- Metrics->IncAlertMsgs();
- break;
- case ::NActors::NLog::EPrio::Emerg:
- Metrics->IncEmergMsgs();
- break;
- default:
- break;
- }
-
- }
-
- void TLoggerActor::HandleLogEvent(NLog::TEvLog::TPtr& ev, const NActors::TActorContext& ctx) {
- i64 delayMillisec = (ctx.Now() - ev->Get()->Stamp).MilliSeconds();
- WriteMessageStat(*ev->Get());
- if (Settings->AllowDrop) {
- if (PassedCount > 10 && delayMillisec > (i64)Settings->TimeThresholdMs || !LogBuffer.IsEmpty() || LogBuffer.CheckLogIgnoring()) {
- if (LogBuffer.IsEmpty() && !LogBuffer.CheckLogIgnoring()) {
- ctx.Send(ctx.SelfID, new TFlushLogBuffer());
- }
- LogBuffer.AddLog(ev->Release().Release());
- PassedCount = 0;
-
- if (delayMillisec < (i64)Settings->TimeThresholdMs && !LogBuffer.CheckLogIgnoring()) {
- FlushLogBufferMessage();
- }
- return;
- }
-
- PassedCount++;
- }
-
- if (!OutputRecord(ev->Get())) {
- BecomeDefunct();
- }
- }
-
- void TLoggerActor::BecomeDefunct() {
- Become(&TThis::StateDefunct);
- Schedule(WakeupInterval, new TEvents::TEvWakeup);
- }
-
- void TLoggerActor::HandleLogComponentLevelRequest(TLogComponentLevelRequest::TPtr& ev, const NActors::TActorContext& ctx) {
- Metrics->IncLevelRequests();
- TString explanation;
- int code = Settings->SetLevel(ev->Get()->Priority, ev->Get()->Component, explanation);
- ctx.Send(ev->Sender, new TLogComponentLevelResponse(code, explanation));
- }
-
- void TLoggerActor::RenderComponentPriorities(IOutputStream& str) {
- using namespace NLog;
- HTML(str) {
- TAG(TH4) {
- str << "Priority Settings for the Components";
- }
- TABLE_SORTABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- str << "Component";
- }
- TABLEH() {
- str << "Level";
- }
- TABLEH() {
- str << "Sampling Level";
- }
- TABLEH() {
- str << "Sampling Rate";
- }
- }
- }
- TABLEBODY() {
- for (EComponent i = Settings->MinVal; i < Settings->MaxVal; i++) {
- auto name = Settings->ComponentName(i);
- if (!*name)
- continue;
- NLog::TComponentSettings componentSettings = Settings->GetComponentSettings(i);
-
- TABLER() {
- TABLED() {
- str << "<a href='logger?c=" << i << "'>" << name << "</a>";
- }
- TABLED() {
- str << PriorityToString(EPrio(componentSettings.Raw.X.Level));
- }
- TABLED() {
- str << PriorityToString(EPrio(componentSettings.Raw.X.SamplingLevel));
- }
- TABLED() {
- str << componentSettings.Raw.X.SamplingRate;
- }
- }
- }
- }
- }
- }
- }
-
- /*
- * Logger INFO:
- * 1. Current priority settings from components
- * 2. Number of log messages (via actors events, directly)
- * 3. Number of messages per components, per priority
- * 4. Log level changes (last N changes)
- */
- void TLoggerActor::HandleMonInfo(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx) {
- const auto& params = ev->Get()->Request.GetParams();
- NLog::EComponent component = NLog::InvalidComponent;
- NLog::EPriority priority = NLog::PRI_DEBUG;
- NLog::EPriority samplingPriority = NLog::PRI_DEBUG;
- ui32 samplingRate = 0;
- bool hasComponent = false;
- bool hasPriority = false;
- bool hasSamplingPriority = false;
- bool hasSamplingRate = false;
- bool hasAllowDrop = false;
- int allowDrop = 0;
- if (params.Has("c")) {
- if (TryFromString(params.Get("c"), component) && (component == NLog::InvalidComponent || Settings->IsValidComponent(component))) {
- hasComponent = true;
- if (params.Has("p")) {
- int rawPriority;
- if (TryFromString(params.Get("p"), rawPriority) && NLog::TSettings::IsValidPriority((NLog::EPriority)rawPriority)) {
- priority = (NLog::EPriority)rawPriority;
- hasPriority = true;
- }
- }
- if (params.Has("sp")) {
- int rawPriority;
- if (TryFromString(params.Get("sp"), rawPriority) && NLog::TSettings::IsValidPriority((NLog::EPriority)rawPriority)) {
- samplingPriority = (NLog::EPriority)rawPriority;
- hasSamplingPriority = true;
- }
- }
- if (params.Has("sr")) {
- if (TryFromString(params.Get("sr"), samplingRate)) {
- hasSamplingRate = true;
- }
- }
- }
- }
- if (params.Has("allowdrop")) {
- if (TryFromString(params.Get("allowdrop"), allowDrop)) {
- hasAllowDrop = true;
- }
- }
-
- TStringStream str;
- if (hasComponent && !hasPriority && !hasSamplingPriority && !hasSamplingRate) {
- NLog::TComponentSettings componentSettings = Settings->GetComponentSettings(component);
- ui32 samplingRate = componentSettings.Raw.X.SamplingRate;
- HTML(str) {
- DIV_CLASS("row") {
- DIV_CLASS("col-md-12") {
- TAG(TH4) {
- str << "Current log settings for " << Settings->ComponentName(component) << Endl;
- }
- UL() {
- LI() {
- str << "Priority: "
- << NLog::PriorityToString(NLog::EPrio(componentSettings.Raw.X.Level));
- }
- LI() {
- str << "Sampling priority: "
- << NLog::PriorityToString(NLog::EPrio(componentSettings.Raw.X.SamplingLevel));
- }
- LI() {
- str << "Sampling rate: "
- << samplingRate;
- }
- }
- }
- }
-
- DIV_CLASS("row") {
- DIV_CLASS("col-md-12") {
- TAG(TH4) {
- str << "Change priority" << Endl;
- }
- UL() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
- LI() {
- str << "<a href='logger?c=" << component << "&p=" << p << "'>"
- << NLog::PriorityToString(NLog::EPrio(p)) << "</a>";
- }
- }
- }
- TAG(TH4) {
- str << "Change sampling priority" << Endl;
- }
- UL() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
- LI() {
- str << "<a href='logger?c=" << component << "&sp=" << p << "'>"
- << NLog::PriorityToString(NLog::EPrio(p)) << "</a>";
- }
- }
- }
- TAG(TH4) {
- str << "Change sampling rate" << Endl;
- }
- str << "<form method=\"GET\">" << Endl;
- str << "Rate: <input type=\"number\" name=\"sr\" value=\"" << samplingRate << "\"/>" << Endl;
- str << "<input type=\"hidden\" name=\"c\" value=\"" << component << "\">" << Endl;
- str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"Change\"/>" << Endl;
- str << "</form>" << Endl;
- TAG(TH4) {
- str << "<a href='logger'>Cancel</a>" << Endl;
- }
- }
- }
- }
-
- } else {
- TString explanation;
- if (hasComponent && hasPriority) {
- Settings->SetLevel(priority, component, explanation);
- }
- if (hasComponent && hasSamplingPriority) {
- Settings->SetSamplingLevel(samplingPriority, component, explanation);
- }
- if (hasComponent && hasSamplingRate) {
- Settings->SetSamplingRate(samplingRate, component, explanation);
- }
- if (hasAllowDrop) {
- Settings->SetAllowDrop(allowDrop);
- }
-
- HTML(str) {
- if (!explanation.empty()) {
- DIV_CLASS("row") {
- DIV_CLASS("col-md-12 alert alert-info") {
- str << explanation;
- }
- }
- }
-
- DIV_CLASS("row") {
- DIV_CLASS("col-md-6") {
- RenderComponentPriorities(str);
- }
- DIV_CLASS("col-md-6") {
- TAG(TH4) {
- str << "Change priority for all components";
- }
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- str << "Priority";
- }
- }
- }
- TABLEBODY() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
- TABLER() {
- TABLED() {
- str << "<a href = 'logger?c=-1&p=" << p << "'>"
- << NLog::PriorityToString(NLog::EPrio(p)) << "</a>";
- }
- }
- }
- }
- }
- TAG(TH4) {
- str << "Change sampling priority for all components";
- }
- TABLE_CLASS("table table-condensed") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- str << "Priority";
- }
- }
- }
- TABLEBODY() {
- for (int p = NLog::PRI_EMERG; p <= NLog::PRI_TRACE; ++p) {
- TABLER() {
- TABLED() {
- str << "<a href = 'logger?c=-1&sp=" << p << "'>"
- << NLog::PriorityToString(NLog::EPrio(p)) << "</a>";
- }
- }
- }
- }
- }
- TAG(TH4) {
- str << "Change sampling rate for all components";
- }
- str << "<form method=\"GET\">" << Endl;
- str << "Rate: <input type=\"number\" name=\"sr\" value=\"0\"/>" << Endl;
- str << "<input type=\"hidden\" name=\"c\" value=\"-1\">" << Endl;
- str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"Change\"/>" << Endl;
- str << "</form>" << Endl;
- TAG(TH4) {
- str << "Drop log entries in case of overflow: "
- << (Settings->AllowDrop ? "Enabled" : "Disabled");
- }
- str << "<form method=\"GET\">" << Endl;
- str << "<input type=\"hidden\" name=\"allowdrop\" value=\"" << (Settings->AllowDrop ? "0" : "1") << "\"/>" << Endl;
- str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"" << (Settings->AllowDrop ? "Disable" : "Enable") << "\"/>" << Endl;
- str << "</form>" << Endl;
- }
- }
- Metrics->GetOutputHtml(str);
- }
- }
-
- ctx.Send(ev->Sender, new NMon::TEvHttpInfoRes(str.Str()));
- }
-
- constexpr size_t TimeBufSize = 512;
-
- bool TLoggerActor::OutputRecord(NLog::TEvLog *evLog) noexcept {
- return OutputRecord(evLog->Stamp, evLog->Level.ToPrio(), evLog->Component, evLog->Line);
- }
-
- bool TLoggerActor::OutputRecord(TInstant time, NLog::EPrio priority, NLog::EComponent component,
- const TString& formatted) noexcept try {
- const auto logPrio = ::ELogPriority(ui16(priority));
-
- char buf[TimeBufSize];
- switch (Settings->Format) {
- case NActors::NLog::TSettings::PLAIN_FULL_FORMAT: {
- TStringBuilder logRecord;
- if (Settings->UseLocalTimestamps) {
- logRecord << FormatLocalTimestamp(time, buf);
- } else {
- logRecord << time;
- }
- logRecord
- << Settings->MessagePrefix
- << " :" << Settings->ComponentName(component)
- << " " << PriorityToString(priority)
- << ": " << formatted;
- LogBackend->WriteData(
- TLogRecord(logPrio, logRecord.data(), logRecord.size()));
- } break;
-
- case NActors::NLog::TSettings::PLAIN_SHORT_FORMAT: {
- TStringBuilder logRecord;
- logRecord
- << Settings->ComponentName(component)
- << ": " << formatted;
- LogBackend->WriteData(
- TLogRecord(logPrio, logRecord.data(), logRecord.size()));
- } break;
-
- case NActors::NLog::TSettings::JSON_FORMAT: {
- NJsonWriter::TBuf json;
- json.BeginObject()
- .WriteKey("@timestamp")
- .WriteString(Settings->UseLocalTimestamps ? FormatLocalTimestamp(time, buf) : time.ToString().data())
- .WriteKey("microseconds")
- .WriteULongLong(time.MicroSeconds())
- .WriteKey("host")
- .WriteString(Settings->ShortHostName)
- .WriteKey("cluster")
- .WriteString(Settings->ClusterName)
- .WriteKey("priority")
- .WriteString(PriorityToString(priority))
- .WriteKey("npriority")
- .WriteInt((int)priority)
- .WriteKey("component")
- .WriteString(Settings->ComponentName(component))
- .WriteKey("tag")
- .WriteString("KIKIMR")
- .WriteKey("revision")
- .WriteInt(GetProgramSvnRevision())
- .WriteKey("message")
- .WriteString(formatted)
- .EndObject();
- auto logRecord = json.Str();
- LogBackend->WriteData(
- TLogRecord(logPrio, logRecord.data(), logRecord.size()));
- } break;
- }
-
- return true;
- } catch (...) {
- return false;
- }
-
- void TLoggerActor::HandleLogEventDrop(const NLog::TEvLog::TPtr& ev) {
- WriteMessageStat(*ev->Get());
- Metrics->IncDroppedMsgs();
- }
-
- void TLoggerActor::HandleWakeup() {
- Become(&TThis::StateFunc);
- }
-
- const char* TLoggerActor::FormatLocalTimestamp(TInstant time, char* buf) {
- struct tm localTime;
- time.LocalTime(&localTime);
- int r = strftime(buf, TimeBufSize, "%Y-%m-%d-%H-%M-%S", &localTime);
- Y_ABORT_UNLESS(r != 0);
- return buf;
- }
-
- TAutoPtr<TLogBackend> CreateSysLogBackend(const TString& ident,
- bool logPError, bool logCons) {
- int flags = 0;
- if (logPError)
- flags |= TSysLogBackend::LogPerror;
- if (logCons)
- flags |= TSysLogBackend::LogCons;
-
- return new TSysLogBackend(ident.data(), TSysLogBackend::TSYSLOG_LOCAL1, flags);
- }
-
- class TStderrBackend: public TLogBackend {
- public:
- TStderrBackend() {
- }
- void WriteData(const TLogRecord& rec) override {
-#ifdef _MSC_VER
- if (IsDebuggerPresent()) {
- TString x;
- x.reserve(rec.Len + 2);
- x.append(rec.Data, rec.Len);
- x.append('\n');
- OutputDebugString(x.c_str());
- }
-#endif
- bool isOk = false;
- do {
- try {
- TRecordWithNewline r(rec);
- Cerr.Write(r.Buf.Data(), r.Buf.Filled());
- isOk = true;
- } catch (TSystemError err) {
- // Interrupted system call
- Y_UNUSED(err);
- }
- } while (!isOk);
- }
-
- void ReopenLog() override {
- }
-
- private:
- const TString Indent;
- };
-
- class TLineFileLogBackend: public TFileLogBackend {
- public:
- TLineFileLogBackend(const TString& path)
- : TFileLogBackend(path)
- {
- }
-
- // Append newline after every record
- void WriteData(const TLogRecord& rec) override {
- TFileLogBackend::WriteData(TRecordWithNewline(rec));
- }
- };
-
- class TCompositeLogBackend: public TLogBackend {
- public:
- TCompositeLogBackend(TVector<TAutoPtr<TLogBackend>>&& underlyingBackends)
- : UnderlyingBackends(std::move(underlyingBackends))
- {
- }
-
- void WriteData(const TLogRecord& rec) override {
- for (auto& b: UnderlyingBackends) {
- b->WriteData(rec);
- }
- }
-
- void ReopenLog() override {
- }
-
- private:
- TVector<TAutoPtr<TLogBackend>> UnderlyingBackends;
- };
-
- TAutoPtr<TLogBackend> CreateStderrBackend() {
- return new TStderrBackend();
- }
-
- TAutoPtr<TLogBackend> CreateFileBackend(const TString& fileName) {
- return new TLineFileLogBackend(fileName);
- }
-
- TAutoPtr<TLogBackend> CreateNullBackend() {
- return new TNullLogBackend();
- }
-
- TAutoPtr<TLogBackend> CreateCompositeLogBackend(TVector<TAutoPtr<TLogBackend>>&& underlyingBackends) {
- return new TCompositeLogBackend(std::move(underlyingBackends));
- }
-
- class TLogContext: TNonCopyable {
- private:
- class TStackedContext {
- private:
- const TLogContextGuard* Guard;
- std::optional<NLog::EComponent> Component;
- mutable std::optional<TString> CurrentHeader;
- public:
- TStackedContext(const TLogContextGuard* guard, std::optional<NLog::EComponent>&& component)
- : Guard(guard)
- , Component(std::move(component))
- {
-
- }
-
- ui64 GetId() const {
- return Guard->GetId();
- }
-
- const std::optional<NLog::EComponent>& GetComponent() const {
- return Component;
- }
-
- TString GetCurrentHeader() const {
- if (!CurrentHeader) {
- CurrentHeader = Guard->GetResult();
- }
- return *CurrentHeader;
- }
- };
-
- std::vector<TStackedContext> Stack;
- public:
- void Push(const TLogContextGuard& context) {
- std::optional<NLog::EComponent> component;
- if (Stack.empty() || context.GetComponent()) {
- component = context.GetComponent();
- } else {
- component = Stack.back().GetComponent();
- }
- Stack.emplace_back(&context, std::move(component));
- }
-
- void Pop(const TLogContextGuard& context) {
- Y_ABORT_UNLESS(Stack.size() && Stack.back().GetId() == context.GetId());
- Stack.pop_back();
- }
-
- std::optional<NLog::EComponent> GetCurrentComponent() const {
- if (Stack.empty()) {
- return {};
- }
- return Stack.back().GetComponent();
- }
-
- TString GetCurrentHeader() {
- TStringBuilder sb;
- for (auto&& i : Stack) {
- sb << i.GetCurrentHeader();
- }
- return sb;
- }
- };
-
- namespace {
- Y_POD_THREAD(ui64) GuardId;
- Y_THREAD(TLogContext) TlsLogContext;
-
- }
-
- TLogContextGuard::~TLogContextGuard() {
- TlsLogContext.Get().Pop(*this);
- }
-
- TLogContextGuard::TLogContextGuard(const TLogContextBuilder& builder)
- : TBase(builder.GetResult())
- , Component(builder.GetComponent())
- , Id(++GuardId)
- {
- TlsLogContext.Get().Push(*this);
- }
-
- int TLogContextGuard::GetCurrentComponent(const ::NActors::NLog::EComponent defComponent) {
- return TlsLogContext.Get().GetCurrentComponent().value_or(defComponent);
- }
-
- TLogRecordConstructor::TLogRecordConstructor() {
- TBase::WriteDirectly(TlsLogContext.Get().GetCurrentHeader());
- }
-
- TFormattedRecordWriter::TFormattedRecordWriter(::NActors::NLog::EPriority priority, ::NActors::NLog::EComponent component)
- : ActorContext(NActors::TlsActivationContext ? &NActors::TlsActivationContext->AsActorContext() : nullptr)
- , Priority(priority)
- , Component(component) {
- TBase::WriteDirectly(TlsLogContext.Get().GetCurrentHeader());
- }
-
- TFormattedRecordWriter::~TFormattedRecordWriter() {
- if (ActorContext) {
- ::NActors::MemLogAdapter(*ActorContext, Priority, Component, TBase::GetResult());
- } else {
- Cerr << "FALLBACK_ACTOR_LOGGING;priority=" << Priority << ";component=" << Component << ";" << TBase::GetResult() << Endl;
- }
- }
-
- TVerifyFormattedRecordWriter::TVerifyFormattedRecordWriter(const TString& conditionText)
- : ConditionText(conditionText) {
- TBase::WriteDirectly(TlsLogContext.Get().GetCurrentHeader());
- TBase::Write("verification", ConditionText);
-
- }
-
- TVerifyFormattedRecordWriter::~TVerifyFormattedRecordWriter() {
- const TString data = TBase::GetResult();
- Y_ABORT("%s", data.data());
- }
-
- TEnsureFormattedRecordWriter::TEnsureFormattedRecordWriter(const TString& conditionText)
- : ConditionText(conditionText) {
- TBase::WriteDirectly(TlsLogContext.Get().GetCurrentHeader());
- TBase::Write("verification", ConditionText);
-
- }
-
- TEnsureFormattedRecordWriter::~TEnsureFormattedRecordWriter() noexcept(false) {
- const TString data = TBase::GetResult();
- if (NActors::TlsActivationContext) {
- ::NActors::MemLogAdapter(NActors::TlsActivationContext->AsActorContext(), NLog::EPriority::PRI_ERROR, 0, data);
- } else {
- Cerr << "FALLBACK_EXCEPTION_LOGGING;component=EXCEPTION;" << data << Endl;
- }
- if (!std::uncaught_exceptions()) {
- Y_ENSURE(false, data.data());
- } else {
- Y_ABORT("%s", data.data());
- }
- }
-
-}
diff --git a/library/cpp/actors/core/log.h b/library/cpp/actors/core/log.h
deleted file mode 100644
index 9f1d367932..0000000000
--- a/library/cpp/actors/core/log.h
+++ /dev/null
@@ -1,627 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-#include "log_iface.h"
-#include "log_settings.h"
-#include "log_metrics.h"
-#include "log_buffer.h"
-#include "actorsystem.h"
-#include "events.h"
-#include "event_local.h"
-#include "hfunc.h"
-#include "mon.h"
-
-#include <util/generic/vector.h>
-#include <util/string/printf.h>
-#include <util/string/builder.h>
-#include <util/system/yassert.h>
-#include <library/cpp/logger/all.h>
-#include <library/cpp/json/writer/json.h>
-#include <library/cpp/svnversion/svnversion.h>
-
-#include <library/cpp/actors/memory_log/memlog.h>
-
-// TODO: limit number of messages per second
-// TODO: make TLogComponentLevelRequest/Response network messages
-
-#define IS_LOG_PRIORITY_ENABLED(priority, component) \
- [p = static_cast<::NActors::NLog::EPriority>(priority), c = static_cast<::NActors::NLog::EComponent>(component)]() -> bool { \
- ::NActors::TActivationContext *context = ::NActors::TlsActivationContext; \
- return !context || context->LoggerSettings()->Satisfies(p, c, 0ull); \
- }()
-
-#define IS_EMERG_LOG_ENABLED(component) IS_LOG_PRIORITY_ENABLED(NActors::NLog::PRI_EMERG, component)
-#define IS_ALERT_LOG_ENABLED(component) IS_LOG_PRIORITY_ENABLED(NActors::NLog::PRI_ALERT, component)
-#define IS_CRIT_LOG_ENABLED(component) IS_LOG_PRIORITY_ENABLED(NActors::NLog::PRI_CRIT, component)
-#define IS_ERROR_LOG_ENABLED(component) IS_LOG_PRIORITY_ENABLED(NActors::NLog::PRI_ERROR, component)
-#define IS_WARN_LOG_ENABLED(component) IS_LOG_PRIORITY_ENABLED(NActors::NLog::PRI_WARN, component)
-#define IS_NOTICE_LOG_ENABLED(component) IS_LOG_PRIORITY_ENABLED(NActors::NLog::PRI_NOTICE, component)
-#define IS_INFO_LOG_ENABLED(component) IS_LOG_PRIORITY_ENABLED(NActors::NLog::PRI_INFO, component)
-#define IS_DEBUG_LOG_ENABLED(component) IS_LOG_PRIORITY_ENABLED(NActors::NLog::PRI_DEBUG, component)
-#define IS_TRACE_LOG_ENABLED(component) IS_LOG_PRIORITY_ENABLED(NActors::NLog::PRI_TRACE, component)
-
-#define LOG_LOG_SAMPLED_BY(actorCtxOrSystem, priority, component, sampleBy, ...) \
- do { \
- ::NActors::NLog::TSettings* mSettings = static_cast<::NActors::NLog::TSettings*>((actorCtxOrSystem).LoggerSettings()); \
- ::NActors::NLog::EPriority mPriority = static_cast<::NActors::NLog::EPriority>(priority); \
- ::NActors::NLog::EComponent mComponent = static_cast<::NActors::NLog::EComponent>(component); \
- if (mSettings && mSettings->Satisfies(mPriority, mComponent, sampleBy)) { \
- ::NActors::MemLogAdapter( \
- actorCtxOrSystem, priority, component, __VA_ARGS__); \
- } \
- } while (0) /**/
-
-#define LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, sampleBy, stream) \
- LOG_LOG_SAMPLED_BY(actorCtxOrSystem, priority, component, sampleBy, [&]() -> TString { \
- TStringBuilder logStringBuilder; \
- logStringBuilder << stream; \
- return std::move(logStringBuilder); \
- }())
-
-#define LOG_LOG(actorCtxOrSystem, priority, component, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, priority, component, 0ull, __VA_ARGS__)
-#define LOG_LOG_S(actorCtxOrSystem, priority, component, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, priority, component, 0ull, stream)
-
-// use these macros for logging via actor system or actor context
-#define LOG_EMERG(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, __VA_ARGS__)
-#define LOG_ALERT(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, __VA_ARGS__)
-#define LOG_CRIT(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, __VA_ARGS__)
-#define LOG_ERROR(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, __VA_ARGS__)
-#define LOG_WARN(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, __VA_ARGS__)
-#define LOG_NOTICE(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_NOTICE, component, __VA_ARGS__)
-#define LOG_INFO(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, __VA_ARGS__)
-#define LOG_DEBUG(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, __VA_ARGS__)
-#define LOG_TRACE(actorCtxOrSystem, component, ...) LOG_LOG(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, __VA_ARGS__)
-
-#define LOG_EMERG_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, stream)
-#define LOG_ALERT_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, stream)
-#define LOG_CRIT_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, stream)
-#define LOG_ERROR_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, stream)
-#define LOG_WARN_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, stream)
-#define LOG_NOTICE_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_NOTICE, component, stream)
-#define LOG_INFO_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, stream)
-#define LOG_DEBUG_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, stream)
-#define LOG_TRACE_S(actorCtxOrSystem, component, stream) LOG_LOG_S(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, stream)
-
-#define ALOG_EMERG(component, stream) LOG_LOG_S(*NActors::TlsActivationContext, NActors::NLog::PRI_EMERG, component, stream)
-#define ALOG_ALERT(component, stream) LOG_LOG_S(*NActors::TlsActivationContext, NActors::NLog::PRI_ALERT, component, stream)
-#define ALOG_CRIT(component, stream) LOG_LOG_S(*NActors::TlsActivationContext, NActors::NLog::PRI_CRIT, component, stream)
-#define ALOG_ERROR(component, stream) LOG_LOG_S(*NActors::TlsActivationContext, NActors::NLog::PRI_ERROR, component, stream)
-#define ALOG_WARN(component, stream) LOG_LOG_S(*NActors::TlsActivationContext, NActors::NLog::PRI_WARN, component, stream)
-#define ALOG_NOTICE(component, stream) LOG_LOG_S(*NActors::TlsActivationContext, NActors::NLog::PRI_NOTICE, component, stream)
-#define ALOG_INFO(component, stream) LOG_LOG_S(*NActors::TlsActivationContext, NActors::NLog::PRI_INFO, component, stream)
-#define ALOG_DEBUG(component, stream) LOG_LOG_S(*NActors::TlsActivationContext, NActors::NLog::PRI_DEBUG, component, stream)
-#define ALOG_TRACE(component, stream) LOG_LOG_S(*NActors::TlsActivationContext, NActors::NLog::PRI_TRACE, component, stream)
-
-#define LOG_EMERG_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, sampleBy, __VA_ARGS__)
-#define LOG_ALERT_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, sampleBy, __VA_ARGS__)
-#define LOG_CRIT_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, sampleBy, __VA_ARGS__)
-#define LOG_ERROR_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, sampleBy, __VA_ARGS__)
-#define LOG_WARN_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, sampleBy, __VA_ARGS__)
-#define LOG_NOTICE_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_NOTICE, component, sampleBy, __VA_ARGS__)
-#define LOG_INFO_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, sampleBy, __VA_ARGS__)
-#define LOG_DEBUG_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, sampleBy, __VA_ARGS__)
-#define LOG_TRACE_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, ...) LOG_LOG_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, sampleBy, __VA_ARGS__)
-
-#define LOG_EMERG_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_EMERG, component, sampleBy, stream)
-#define LOG_ALERT_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ALERT, component, sampleBy, stream)
-#define LOG_CRIT_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_CRIT, component, sampleBy, stream)
-#define LOG_ERROR_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_ERROR, component, sampleBy, stream)
-#define LOG_WARN_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_WARN, component, sampleBy, stream)
-#define LOG_NOTICE_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_NOTICE, component, sampleBy, stream)
-#define LOG_INFO_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_INFO, component, sampleBy, stream)
-#define LOG_DEBUG_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_DEBUG, component, sampleBy, stream)
-#define LOG_TRACE_S_SAMPLED_BY(actorCtxOrSystem, component, sampleBy, stream) LOG_LOG_S_SAMPLED_BY(actorCtxOrSystem, NActors::NLog::PRI_TRACE, component, sampleBy, stream)
-
-// Log Throttling
-#define LOG_LOG_THROTTLE(throttler, actorCtxOrSystem, priority, component, ...) \
- do { \
- if ((throttler).Kick()) { \
- LOG_LOG(actorCtxOrSystem, priority, component, __VA_ARGS__); \
- } \
- } while (0) /**/
-
-#define LOG_LOG_S_THROTTLE(throttler, actorCtxOrSystem, priority, component, stream) \
- do { \
- if ((throttler).Kick()) { \
- LOG_LOG_S(actorCtxOrSystem, priority, component, stream); \
- } \
- } while (0) /**/
-
-#define TRACE_EVENT(component) \
- const auto& currentTracer = component; \
- if (ev->HasEvent()) { \
- LOG_TRACE(*TlsActivationContext, currentTracer, "%s, received event# %" PRIu32 ", Sender %s, Recipient %s: %s", \
- __FUNCTION__, ev->Type, ev->Sender.ToString().data(), SelfId().ToString().data(), ev->ToString().substr(0, 1000).data()); \
- } else { \
- LOG_TRACE(*TlsActivationContext, currentTracer, "%s, received event# %" PRIu32 ", Sender %s, Recipient %s", \
- __FUNCTION__, ev->Type, ev->Sender.ToString().data(), ev->Recipient.ToString().data()); \
- }
-#define TRACE_EVENT_TYPE(eventType) LOG_TRACE(*TlsActivationContext, currentTracer, "%s, processing event %s", __FUNCTION__, eventType)
-
-class TLog;
-class TLogBackend;
-
-namespace NActors {
- class TLoggerActor;
-
- ////////////////////////////////////////////////////////////////////////////////
- // SET LOG LEVEL FOR A COMPONENT
- ////////////////////////////////////////////////////////////////////////////////
- class TLogComponentLevelRequest: public TEventLocal<TLogComponentLevelRequest, int(NLog::EEv::LevelReq)> {
- public:
- // set given priority for the component
- TLogComponentLevelRequest(NLog::EPriority priority, NLog::EComponent component)
- : Priority(priority)
- , Component(component)
- {
- }
-
- // set given priority for all components
- TLogComponentLevelRequest(NLog::EPriority priority)
- : Priority(priority)
- , Component(NLog::InvalidComponent)
- {
- }
-
- protected:
- NLog::EPriority Priority;
- NLog::EComponent Component;
-
- friend class TLoggerActor;
- };
-
- class TLogComponentLevelResponse: public TEventLocal<TLogComponentLevelResponse, int(NLog::EEv::LevelResp)> {
- public:
- TLogComponentLevelResponse(int code, const TString& explanation)
- : Code(code)
- , Explanation(explanation)
- {
- }
-
- int GetCode() const {
- return Code;
- }
-
- const TString& GetExplanation() const {
- return Explanation;
- }
-
- protected:
- int Code;
- TString Explanation;
- };
-
- class TFlushLogBuffer: public TEventLocal<TFlushLogBuffer, int(NLog::EEv::Buffer)> {
- public:
- TFlushLogBuffer() {
- }
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // LOGGER ACTOR
- ////////////////////////////////////////////////////////////////////////////////
- class TLoggerActor: public TActor<TLoggerActor> {
- public:
- static IActor::EActivityType ActorActivityType() {
- return IActor::EActivityType::LOG_ACTOR;
- }
-
- TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- TAutoPtr<TLogBackend> logBackend,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters);
- TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- std::shared_ptr<TLogBackend> logBackend,
- TIntrusivePtr<NMonitoring::TDynamicCounters> counters);
- TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- TAutoPtr<TLogBackend> logBackend,
- std::shared_ptr<NMonitoring::TMetricRegistry> metrics);
- TLoggerActor(TIntrusivePtr<NLog::TSettings> settings,
- std::shared_ptr<TLogBackend> logBackend,
- std::shared_ptr<NMonitoring::TMetricRegistry> metrics);
- ~TLoggerActor();
-
- void StateFunc(TAutoPtr<IEventHandle>& ev) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TFlushLogBuffer, FlushLogBufferMessageEvent);
- HFunc(NLog::TEvLog, HandleLogEvent);
- HFunc(TLogComponentLevelRequest, HandleLogComponentLevelRequest);
- HFunc(NMon::TEvHttpInfo, HandleMonInfo);
- }
- }
-
- STFUNC(StateDefunct) {
- switch (ev->GetTypeRewrite()) {
- hFunc(NLog::TEvLog, HandleLogEventDrop);
- HFunc(TLogComponentLevelRequest, HandleLogComponentLevelRequest);
- HFunc(NMon::TEvHttpInfo, HandleMonInfo);
- cFunc(TEvents::TEvWakeup::EventType, HandleWakeup);
- }
- }
-
- // Directly call logger instead of sending a message
- void Log(TInstant time, NLog::EPriority priority, NLog::EComponent component, const char* c, ...);
-
- static void Throttle(const NLog::TSettings& settings);
-
- private:
- TIntrusivePtr<NLog::TSettings> Settings;
- std::shared_ptr<TLogBackend> LogBackend;
- ui64 PassedCount = 0;
- TDuration WakeupInterval{TDuration::Seconds(5)};
- std::unique_ptr<ILoggerMetrics> Metrics;
- TLogBuffer LogBuffer;
-
- void BecomeDefunct();
- void FlushLogBufferMessageEvent(TFlushLogBuffer::TPtr& ev, const NActors::TActorContext& ctx);
- void HandleLogEvent(NLog::TEvLog::TPtr& ev, const TActorContext& ctx);
- void HandleLogEventDrop(const NLog::TEvLog::TPtr& ev);
- void HandleLogComponentLevelRequest(TLogComponentLevelRequest::TPtr& ev, const TActorContext& ctx);
- void HandleMonInfo(NMon::TEvHttpInfo::TPtr& ev, const TActorContext& ctx);
- void HandleWakeup();
- [[nodiscard]] bool OutputRecord(NLog::TEvLog *evLog) noexcept;
- [[nodiscard]] bool OutputRecord(TInstant time, NLog::EPrio priority, NLog::EComponent component, const TString& formatted) noexcept;
- void RenderComponentPriorities(IOutputStream& str);
- void FlushLogBufferMessage();
- void WriteMessageStat(const NLog::TEvLog& ev);
- static const char* FormatLocalTimestamp(TInstant time, char* buf);
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // LOG THROTTLING
- // TTrivialLogThrottler -- log a message every 'period' duration
- // Use case:
- // TTrivialLogThrottler throttler(TDuration::Minutes(1));
- // ....
- // LOG_LOG_THROTTLE(throttler, ctx, NActors::NLog::PRI_ERROR, SOME, "Error");
- ////////////////////////////////////////////////////////////////////////////////
- class TTrivialLogThrottler {
- public:
- TTrivialLogThrottler(TDuration period)
- : Period(period)
- {
- }
-
- // return value:
- // true -- write to log
- // false -- don't write to log, throttle
- bool Kick() {
- auto now = TInstant::Now();
- if (now >= (LastWrite + Period)) {
- LastWrite = now;
- return true;
- } else {
- return false;
- }
- }
-
- private:
- TInstant LastWrite;
- TDuration Period;
- };
-
- ////////////////////////////////////////////////////////////////////////////////
- // SYSLOG BACKEND
- ////////////////////////////////////////////////////////////////////////////////
- TAutoPtr<TLogBackend> CreateSysLogBackend(const TString& ident,
- bool logPError, bool logCons);
- TAutoPtr<TLogBackend> CreateStderrBackend();
- TAutoPtr<TLogBackend> CreateFileBackend(const TString& fileName);
- TAutoPtr<TLogBackend> CreateNullBackend();
- TAutoPtr<TLogBackend> CreateCompositeLogBackend(TVector<TAutoPtr<TLogBackend>>&& underlyingBackends);
-
- /////////////////////////////////////////////////////////////////////
- // Logging adaptors for memory log and logging into filesystem
- /////////////////////////////////////////////////////////////////////
-
- namespace NDetail {
- inline void Y_PRINTF_FORMAT(2, 3) PrintfV(TString& dst, const char* format, ...) {
- va_list params;
- va_start(params, format);
- vsprintf(dst, format, params);
- va_end(params);
- }
-
- inline void PrintfV(TString& dst, const char* format, va_list params) {
- vsprintf(dst, format, params);
- }
- } // namespace NDetail
-
- template <typename TCtx>
- inline void DeliverLogMessage(TCtx& ctx, NLog::EPriority mPriority, NLog::EComponent mComponent, TString &&str)
- {
- const NLog::TSettings *mSettings = ctx.LoggerSettings();
- TLoggerActor::Throttle(*mSettings);
- ctx.Send(new IEventHandle(mSettings->LoggerActorId, TActorId(), new NLog::TEvLog(mPriority, mComponent, std::move(str))));
- }
-
- template <typename TCtx, typename... TArgs>
- inline void MemLogAdapter(
- TCtx& actorCtxOrSystem,
- NLog::EPriority mPriority,
- NLog::EComponent mComponent,
- const char* format, TArgs&&... params) {
- TString Formatted;
-
-
- if constexpr (sizeof... (params) > 0) {
- NDetail::PrintfV(Formatted, format, std::forward<TArgs>(params)...);
- } else {
- NDetail::PrintfV(Formatted, "%s", format);
- }
-
- MemLogWrite(Formatted.data(), Formatted.size(), true);
- DeliverLogMessage(actorCtxOrSystem, mPriority, mComponent, std::move(Formatted));
- }
-
- template <typename TCtx>
- Y_WRAPPER inline void MemLogAdapter(
- TCtx& actorCtxOrSystem,
- NLog::EPriority mPriority,
- NLog::EComponent mComponent,
- const TString& str) {
-
- MemLogWrite(str.data(), str.size(), true);
- DeliverLogMessage(actorCtxOrSystem, mPriority, mComponent, TString(str));
- }
-
- template <typename TCtx>
- Y_WRAPPER inline void MemLogAdapter(
- TCtx& actorCtxOrSystem,
- NLog::EPriority mPriority,
- NLog::EComponent mComponent,
- TString&& str) {
-
- MemLogWrite(str.data(), str.size(), true);
- DeliverLogMessage(actorCtxOrSystem, mPriority, mComponent, std::move(str));
- }
-
- class TRecordWriter: public TStringBuilder {
- private:
- const TActorContext* ActorContext = nullptr;
- ::NActors::NLog::EPriority Priority = ::NActors::NLog::EPriority::PRI_INFO;
- ::NActors::NLog::EComponent Component = 0;
- public:
- TRecordWriter(::NActors::NLog::EPriority priority, ::NActors::NLog::EComponent component)
- : ActorContext(NActors::TlsActivationContext ? &NActors::TlsActivationContext->AsActorContext() : nullptr)
- , Priority(priority)
- , Component(component) {
-
- }
-
- ~TRecordWriter() {
- if (ActorContext) {
- ::NActors::MemLogAdapter(*ActorContext, Priority, Component, *this);
- } else {
- Cerr << "FALLBACK_ACTOR_LOGGING;priority=" << Priority << ";component=" << Component << ";" << static_cast<const TStringBuilder&>(*this) << Endl;
- }
- }
- };
-
- class TFormatedStreamWriter: TNonCopyable {
- private:
- TStringBuilder Builder;
- protected:
- template <class TKey, class TValue>
- TFormatedStreamWriter& Write(const TKey& pName, const TValue& pValue) {
- Builder << pName << "=" << pValue << ";";
- return *this;
- }
-
- template <class TKey, class TValue>
- TFormatedStreamWriter& Write(const TKey& pName, const std::optional<TValue>& pValue) {
- if (pValue) {
- Builder << pName << "=" << *pValue << ";";
- } else {
- Builder << pName << "=NO_VALUE_OPTIONAL;";
- }
- return *this;
- }
-
- TFormatedStreamWriter& WriteDirectly(const TString& data) {
- Builder << data;
- return *this;
- }
- public:
- TFormatedStreamWriter() = default;
- TFormatedStreamWriter(const TString& info) {
- Builder << info;
- }
- const TString& GetResult() const {
- return Builder;
- }
- };
-
- class TLogContextBuilder: public TFormatedStreamWriter {
- private:
- using TBase = TFormatedStreamWriter;
- std::optional<::NActors::NLog::EComponent> Component;
- TLogContextBuilder(std::optional<::NActors::NLog::EComponent> component)
- : Component(component) {
- }
- public:
-
- template <class TKey, class TValue>
- TLogContextBuilder& operator()(const TKey& pName, const TValue& pValue) {
- TBase::Write(pName, pValue);
- return *this;
- }
-
- const std::optional<::NActors::NLog::EComponent>& GetComponent() const {
- return Component;
- }
-
- static TLogContextBuilder Build(std::optional<::NActors::NLog::EComponent> component = {}) {
- return TLogContextBuilder(component);
- }
- };
-
- class TLogContextGuard: public TFormatedStreamWriter {
- private:
- using TBase = TFormatedStreamWriter;
- std::optional<::NActors::NLog::EComponent> Component;
- const ui64 Id = 0;
- public:
- TLogContextGuard(const TLogContextBuilder& builder);
-
- ~TLogContextGuard();
-
- static int GetCurrentComponent(const ::NActors::NLog::EComponent defComponent = 0);
-
- const std::optional<::NActors::NLog::EComponent>& GetComponent() const {
- return Component;
- }
-
- ui64 GetId() const {
- return Id;
- }
-
- template <class TKey, class TValue>
- TLogContextGuard& Write(const TKey& pName, const TValue& pValue) {
- TBase::Write(pName, pValue);
- return *this;
- }
-
- };
-
- class TLogRecordConstructor: public TFormatedStreamWriter {
- private:
- using TBase = TFormatedStreamWriter;
- public:
-
- TLogRecordConstructor();
-
- template <class TKey, class TValue>
- TLogRecordConstructor& operator()(const TKey& pName, const TValue& pValue) {
- TBase::Write(pName, pValue);
- return *this;
- }
- };
-
- class TFormattedRecordWriter: public TFormatedStreamWriter {
- private:
- using TBase = TFormatedStreamWriter;
- const TActorContext* ActorContext = nullptr;
- ::NActors::NLog::EPriority Priority = ::NActors::NLog::EPriority::PRI_INFO;
- ::NActors::NLog::EComponent Component = 0;
- public:
-
- TFormattedRecordWriter(::NActors::NLog::EPriority priority, ::NActors::NLog::EComponent component);
-
- template <class TKey, class TValue>
- TFormattedRecordWriter& operator()(const TKey& pName, const TValue& pValue) {
- TBase::Write(pName, pValue);
- return *this;
- }
-
- ~TFormattedRecordWriter();
- };
-
- class TVerifyFormattedRecordWriter: public TFormatedStreamWriter {
- private:
- using TBase = TFormatedStreamWriter;
- const TString ConditionText;
- public:
-
- TVerifyFormattedRecordWriter(const TString& conditionText);
-
- template <class TKey, class TValue>
- TVerifyFormattedRecordWriter& operator()(const TKey& pName, const TValue& pValue) {
- TBase::Write(pName, pValue);
- return *this;
- }
-
- ~TVerifyFormattedRecordWriter();
- };
-
- class TEnsureFormattedRecordWriter: public TFormatedStreamWriter {
- private:
- using TBase = TFormatedStreamWriter;
- const TString ConditionText;
- public:
-
- TEnsureFormattedRecordWriter(const TString& conditionText);
-
- template <class TKey, class TValue>
- TEnsureFormattedRecordWriter& operator()(const TKey& pName, const TValue& pValue) {
- TBase::Write(pName, pValue);
- return *this;
- }
-
- ~TEnsureFormattedRecordWriter() noexcept(false);
- };
-}
-
-#define AFL_VERIFY(condition) if (condition); else NActors::TVerifyFormattedRecordWriter(#condition)("fline", TStringBuilder() << TStringBuf(__FILE__).RAfter(LOCSLASH_C) << ":" << __LINE__)
-#define AFL_ENSURE(condition) if (condition); else NActors::TEnsureFormattedRecordWriter(#condition)("fline", TStringBuilder() << TStringBuf(__FILE__).RAfter(LOCSLASH_C) << ":" << __LINE__)
-
-#ifndef NDEBUG
-/// Assert that depend on NDEBUG macro and outputs message like printf
-#define AFL_VERIFY_DEBUG AFL_VERIFY
-#else
-#define AFL_VERIFY_DEBUG(condition) if (true); else NActors::TVerifyFormattedRecordWriter(#condition)("fline", TStringBuilder() << TStringBuf(__FILE__).RAfter(LOCSLASH_C) << ":" << __LINE__)
-#endif
-
-#define ACTORS_FORMATTED_LOG(mPriority, mComponent) \
- if (NActors::TlsActivationContext && !IS_LOG_PRIORITY_ENABLED(mPriority, mComponent));\
- else NActors::TFormattedRecordWriter(\
- static_cast<::NActors::NLog::EPriority>(mPriority), static_cast<::NActors::NLog::EComponent>(mComponent)\
- )("fline", TStringBuilder() << TStringBuf(__FILE__).RAfter(LOCSLASH_C) << ":" << __LINE__)
-
-#define ACTORS_LOG_STREAM(mPriority, mComponent) \
- if (NActors::TlsActivationContext && !IS_LOG_PRIORITY_ENABLED(mPriority, mComponent));\
- else NActors::TRecordWriter(\
- static_cast<::NActors::NLog::EPriority>(mPriority), static_cast<::NActors::NLog::EComponent>(mComponent)\
- ) << TStringBuf(__FILE__).RAfter(LOCSLASH_C) << ":" << __LINE__ << " :"
-
-#define ALS_TRACE(component) ACTORS_LOG_STREAM(NActors::NLog::PRI_TRACE, component)
-#define ALS_DEBUG(component) ACTORS_LOG_STREAM(NActors::NLog::PRI_DEBUG, component)
-#define ALS_INFO(component) ACTORS_LOG_STREAM(NActors::NLog::PRI_INFO, component)
-#define ALS_NOTICE(component) ACTORS_LOG_STREAM(NActors::NLog::PRI_NOTICE, component)
-#define ALS_WARN(component) ACTORS_LOG_STREAM(NActors::NLog::PRI_WARN, component)
-#define ALS_ERROR(component) ACTORS_LOG_STREAM(NActors::NLog::PRI_ERROR, component)
-#define ALS_CRIT(component) ACTORS_LOG_STREAM(NActors::NLog::PRI_CRIT, component)
-#define ALS_ALERT(component) ACTORS_LOG_STREAM(NActors::NLog::PRI_ALERT, component)
-#define ALS_EMERG(component) ACTORS_LOG_STREAM(NActors::NLog::PRI_EMERG, component)
-
-#define AFL_TRACE(component) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_TRACE, component)
-#define AFL_DEBUG(component) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_DEBUG, component)
-#define AFL_INFO(component) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_INFO, component)
-#define AFL_NOTICE(component) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_NOTICE, component)
-#define AFL_WARN(component) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_WARN, component)
-#define AFL_ERROR(component) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_ERROR, component)
-#define AFL_CRIT(component) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_CRIT, component)
-#define AFL_ALERT(component) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_ALERT, component)
-#define AFL_EMERG(component) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_EMERG, component)
-
-#define DETECT_LOG_MACRO(_1, _2, NAME, ...) NAME
-
-#define BASE_CFL_TRACE2(k, v) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_TRACE, ::NActors::TLogContextGuard::GetCurrentComponent())(k, v)
-#define BASE_CFL_DEBUG2(k, v) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_DEBUG, ::NActors::TLogContextGuard::GetCurrentComponent())(k, v)
-#define BASE_CFL_INFO2(k, v) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_INFO, ::NActors::TLogContextGuard::GetCurrentComponent())(k, v)
-#define BASE_CFL_NOTICE2(k, v) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_NOTICE, ::NActors::TLogContextGuard::GetCurrentComponent())(k, v)
-#define BASE_CFL_WARN2(k, v) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_WARN, ::NActors::TLogContextGuard::GetCurrentComponent())(k, v)
-#define BASE_CFL_ERROR2(k, v) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_ERROR, ::NActors::TLogContextGuard::GetCurrentComponent())(k, v)
-#define BASE_CFL_CRIT2(k, v) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_CRIT, ::NActors::TLogContextGuard::GetCurrentComponent())(k, v)
-#define BASE_CFL_ALERT2(k, v) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_ALERT, ::NActors::TLogContextGuard::GetCurrentComponent())(k, v)
-#define BASE_CFL_EMERG2(k, v) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_EMERG, ::NActors::TLogContextGuard::GetCurrentComponent())(k, v)
-
-#define BASE_CFL_TRACE1(defaultComponent) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_TRACE, ::NActors::TLogContextGuard::GetCurrentComponent(defaultComponent))
-#define BASE_CFL_DEBUG1(defaultComponent) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_DEBUG, ::NActors::TLogContextGuard::GetCurrentComponent(defaultComponent))
-#define BASE_CFL_INFO1(defaultComponent) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_INFO, ::NActors::TLogContextGuard::GetCurrentComponent(defaultComponent))
-#define BASE_CFL_NOTICE1(defaultComponent) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_NOTICE, ::NActors::TLogContextGuard::GetCurrentComponent(defaultComponent))
-#define BASE_CFL_WARN1(defaultComponent) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_WARN, ::NActors::TLogContextGuard::GetCurrentComponent(defaultComponent))
-#define BASE_CFL_ERROR1(defaultComponent) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_ERROR, ::NActors::TLogContextGuard::GetCurrentComponent(defaultComponent))
-#define BASE_CFL_CRIT1(defaultComponent) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_CRIT, ::NActors::TLogContextGuard::GetCurrentComponent(defaultComponent))
-#define BASE_CFL_ALERT1(defaultComponent) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_ALERT, ::NActors::TLogContextGuard::GetCurrentComponent(defaultComponent))
-#define BASE_CFL_EMERG1(defaultComponent) ACTORS_FORMATTED_LOG(NActors::NLog::PRI_EMERG, ::NActors::TLogContextGuard::GetCurrentComponent(defaultComponent))
-
-#define ACFL_TRACE(...) DETECT_LOG_MACRO(__VA_ARGS__, BASE_CFL_TRACE2, BASE_CFL_TRACE1)(__VA_ARGS__)
-#define ACFL_DEBUG(...) DETECT_LOG_MACRO(__VA_ARGS__, BASE_CFL_DEBUG2, BASE_CFL_DEBUG1)(__VA_ARGS__)
-#define ACFL_INFO(...) DETECT_LOG_MACRO(__VA_ARGS__, BASE_CFL_INFO2, BASE_CFL_INFO1)(__VA_ARGS__)
-#define ACFL_NOTICE(...) DETECT_LOG_MACRO(__VA_ARGS__, BASE_CFL_NOTICE2, BASE_CFL_NOTICE1)(__VA_ARGS__)
-#define ACFL_WARN(...) DETECT_LOG_MACRO(__VA_ARGS__, BASE_CFL_WARN2, BASE_CFL_WARN1)(__VA_ARGS__)
-#define ACFL_ERROR(...) DETECT_LOG_MACRO(__VA_ARGS__, BASE_CFL_ERROR2, BASE_CFL_ERROR1)(__VA_ARGS__)
-#define ACFL_CRIT(...) DETECT_LOG_MACRO(__VA_ARGS__, BASE_CFL_CRIT2, BASE_CFL_CRIT1)(__VA_ARGS__)
-#define ACFL_ALERT(...) DETECT_LOG_MACRO(__VA_ARGS__, BASE_CFL_ALERT2, BASE_CFL_ALERT1)(__VA_ARGS__)
-#define ACFL_EMERG(...) DETECT_LOG_MACRO(__VA_ARGS__, BASE_CFL_EMERG2, BASE_CFL_EMERG1)(__VA_ARGS__)
diff --git a/library/cpp/actors/core/log_buffer.cpp b/library/cpp/actors/core/log_buffer.cpp
deleted file mode 100644
index 8c80f1d054..0000000000
--- a/library/cpp/actors/core/log_buffer.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-#include "log_buffer.h"
-
-#include <util/system/yassert.h>
-#include <algorithm>
-
-using namespace NActors::NLog;
-
-namespace NActors {
-TLogBuffer::TLogBuffer(ILoggerMetrics &metrics, const NLog::TSettings &settings)
- : Metrics(metrics)
- , Settings(settings)
-{}
-
-size_t TLogBuffer::GetLogCostInBytes(NLog::TEvLog *log) const {
- return LOG_STRUCTURE_BYTES + log->Line.length();
-}
-
-ui16 TLogBuffer::GetPrioIndex(NLog::EPrio prio) {
- return Min(ui16(prio), ui16(LOG_PRIORITIES_NUMBER - 1));
-}
-
-TIntrusiveList<NLog::TEvLog, NLog::TEvLogBufferLevelListTag> &TLogBuffer::GetPrioLogs(NLog::EPrio prio) {
- return PrioLogsList[GetPrioIndex(prio)];
-}
-
-void TLogBuffer::AddLog(NLog::TEvLog *log) {
- NLog::EPrio prio = log->Level.ToPrio();
- if (!CheckSize(log) && prio > NLog::EPrio::Emerg) { // always keep logs with prio Emerg = 0
- HandleIgnoredLog(log);
- return;
- }
-
- SizeBytes += GetLogCostInBytes(log);
- Logs.PushBack(log);
- GetPrioLogs(prio).PushBack(log);
-}
-
-NLog::TEvLog* TLogBuffer::Pop() {
- NLog::TEvLog* log = Logs.PopFront();
- static_cast<TIntrusiveListItem<TEvLog, TEvLogBufferLevelListTag>&>(*log).Unlink();
-
- SizeBytes -= GetLogCostInBytes(log);
-
- return log;
-}
-
-bool TLogBuffer::IsEmpty() const {
- return Logs.Empty();
-}
-
-bool TLogBuffer::CheckLogIgnoring() const {
- return IgnoredCount > 0;
-}
-
-bool TLogBuffer::CheckSize(NLog::TEvLog *log) {
- size_t startSizeBytes = SizeBytes;
-
- size_t logSize = GetLogCostInBytes(log);
- if (SizeBytes + logSize <= Settings.BufferSizeLimitBytes) {
- return true;
- }
-
- ui16 scanHighestPrio = Max((ui16)1, GetPrioIndex(log->Level.ToPrio())); // always keep logs with prio Emerg = 0
- for (ui16 scanPrio = LOG_PRIORITIES_NUMBER - 1; scanPrio >= scanHighestPrio; scanPrio--) {
- TIntrusiveList<NLog::TEvLog, NLog::TEvLogBufferLevelListTag> &scanLogs = PrioLogsList[scanPrio];
- while (!scanLogs.Empty()) {
- NLog::TEvLog* log = scanLogs.PopFront();
- SizeBytes -= GetLogCostInBytes(log);
- HandleIgnoredLog(log);
-
- if (SizeBytes + logSize <= Settings.BufferSizeLimitBytes) {
- return true;
- }
- }
- }
-
- if (startSizeBytes > SizeBytes) {
- return true;
- }
-
- return false;
-}
-
-void TLogBuffer::HandleIgnoredLog(NLog::TEvLog *log) {
- ui16 logPrio = GetPrioIndex(log->Level.ToPrio());
- Metrics.IncIgnoredMsgs();
- if (IgnoredHighestPrio > logPrio) {
- IgnoredHighestPrio = logPrio;
- }
- IgnoredCount++;
- delete log;
-}
-
-ui64 TLogBuffer::GetIgnoredCount() {
- return IgnoredCount;
-}
-
-NLog::EPrio TLogBuffer::GetIgnoredHighestPrio() {
- NLog::EPrio prio = static_cast<NLog::EPrio>(IgnoredHighestPrio);
- return prio;
-}
-
-void TLogBuffer::ClearIgnoredCount() {
- IgnoredHighestPrio = LOG_PRIORITIES_NUMBER - 1;
- IgnoredCount = 0;
-}
-
-}
diff --git a/library/cpp/actors/core/log_buffer.h b/library/cpp/actors/core/log_buffer.h
deleted file mode 100644
index 60bc09cc85..0000000000
--- a/library/cpp/actors/core/log_buffer.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include "log_metrics.h"
-#include "log_iface.h"
-#include "log_settings.h"
-
-#include <util/generic/intrlist.h>
-
-namespace NActors {
-class TLogBuffer {
- static const size_t LOG_STRUCTURE_BYTES = sizeof(NLog::TEvLog);
- static const ui16 LOG_PRIORITIES_NUMBER = 9;
-
- ILoggerMetrics &Metrics;
- const NLog::TSettings &Settings;
-
- TIntrusiveListWithAutoDelete<NLog::TEvLog, TDelete, NLog::TEvLogBufferMainListTag> Logs;
- TIntrusiveList<NLog::TEvLog, NLog::TEvLogBufferLevelListTag> PrioLogsList[LOG_PRIORITIES_NUMBER];
-
- ui64 SizeBytes = 0;
- ui64 IgnoredCount = 0;
- ui16 IgnoredHighestPrio = LOG_PRIORITIES_NUMBER - 1;
-
- size_t GetLogCostInBytes(NLog::TEvLog *log) const;
- void HandleIgnoredLog(NLog::TEvLog *log);
- bool CheckSize(NLog::TEvLog *log);
- static inline ui16 GetPrioIndex(NLog::EPrio);
- inline TIntrusiveList<NLog::TEvLog, NLog::TEvLogBufferLevelListTag> &GetPrioLogs(NLog::EPrio);
-
- public:
- TLogBuffer(ILoggerMetrics &metrics, const NLog::TSettings &Settings);
- void AddLog(NLog::TEvLog *log);
- NLog::TEvLog *Pop();
- bool IsEmpty() const;
- bool CheckLogIgnoring() const;
- ui64 GetIgnoredCount();
- NLog::EPrio GetIgnoredHighestPrio();
- void ClearIgnoredCount();
-};
-}
diff --git a/library/cpp/actors/core/log_iface.h b/library/cpp/actors/core/log_iface.h
deleted file mode 100644
index b0195f5581..0000000000
--- a/library/cpp/actors/core/log_iface.h
+++ /dev/null
@@ -1,117 +0,0 @@
-#pragma once
-
-#include "events.h"
-#include "event_local.h"
-
-namespace NActors {
- namespace NLog {
- using EComponent = int;
-
- enum EPriority : ui16 { // migrate it to EPrio whenever possible
- PRI_EMERG /* "EMERG" */,
- PRI_ALERT /* "ALERT" */,
- PRI_CRIT /* "CRIT" */,
- PRI_ERROR /* "ERROR" */,
- PRI_WARN /* "WARN" */,
- PRI_NOTICE /* "NOTICE" */,
- PRI_INFO /* "INFO" */,
- PRI_DEBUG /* "DEBUG" */,
- PRI_TRACE /* "TRACE" */
- };
-
- enum class EPrio : ui16 {
- Emerg = 0,
- Alert = 1,
- Crit = 2,
- Error = 3,
- Warn = 4,
- Notice = 5,
- Info = 6,
- Debug = 7,
- Trace = 8,
- };
-
- struct TLevel {
- TLevel(ui32 raw)
- : Raw(raw)
- {
- }
-
- TLevel(EPrio prio)
- : Raw((ui16(prio) + 1) << 8)
- {
- }
-
- EPrio ToPrio() const noexcept {
- const auto major = Raw >> 8;
-
- return major > 0 ? EPrio(major - 1) : EPrio::Emerg;
- }
-
- bool IsUrgentAbortion() const noexcept {
- return (Raw >> 8) == 0;
- }
-
- /* Generalized monotonic level value composed with major and minor
- levels. Minor is used for verbosity within major, basic EPrio
- mapped to (EPrio + 1, 0) and Major = 0 is reserved as special
- space with meaning like EPrio::Emerg but with extened actions.
- Thus logger should map Major = 0 to EPrio::Emerg if it have no
- idea how to handle special emergency actions.
- */
-
- ui32 Raw = 0; // ((ui16(EPrio) + 1) << 8) | ui8(minor)
- };
-
- enum class EEv {
- Log = EventSpaceBegin(TEvents::ES_LOGGER),
- LevelReq,
- LevelResp,
- Ignored,
- Buffer,
- End
- };
-
- static_assert(int(EEv::End) < EventSpaceEnd(TEvents::ES_LOGGER), "");
-
- struct TEvLogBufferMainListTag {};
- struct TEvLogBufferLevelListTag {};
-
- class TEvLog
- : public TEventLocal<TEvLog, int(EEv::Log)>
- , public TIntrusiveListItem<TEvLog, TEvLogBufferMainListTag>
- , public TIntrusiveListItem<TEvLog, TEvLogBufferLevelListTag>
- {
- public:
- TEvLog(TInstant stamp, TLevel level, EComponent comp, const TString &line)
- : Stamp(stamp)
- , Level(level)
- , Component(comp)
- , Line(line)
- {
- }
-
- TEvLog(TInstant stamp, TLevel level, EComponent comp, TString &&line)
- : Stamp(stamp)
- , Level(level)
- , Component(comp)
- , Line(std::move(line))
- {
- }
-
- TEvLog(EPriority prio, EComponent comp, TString line, TInstant time = TInstant::Now())
- : Stamp(time)
- , Level(EPrio(prio))
- , Component(comp)
- , Line(std::move(line))
- {
- }
-
- const TInstant Stamp = TInstant::Max();
- const TLevel Level;
- const EComponent Component = 0;
- TString Line;
- };
-
- }
-}
diff --git a/library/cpp/actors/core/log_metrics.h b/library/cpp/actors/core/log_metrics.h
deleted file mode 100644
index 5005b2b776..0000000000
--- a/library/cpp/actors/core/log_metrics.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#pragma once
-
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-#include <library/cpp/monlib/metrics/metric_registry.h>
-#include <library/cpp/monlib/service/pages/templates.h>
-
-namespace NActors {
-class ILoggerMetrics {
-public:
- virtual ~ILoggerMetrics() = default;
-
- virtual void IncActorMsgs() = 0;
- virtual void IncDirectMsgs() = 0;
- virtual void IncLevelRequests() = 0;
- virtual void IncIgnoredMsgs() = 0;
- virtual void IncAlertMsgs() = 0;
- virtual void IncEmergMsgs() = 0;
- virtual void IncDroppedMsgs() = 0;
-
- virtual void GetOutputHtml(IOutputStream&) = 0;
-};
-
-class TLoggerCounters : public ILoggerMetrics {
-public:
- TLoggerCounters(TIntrusivePtr<NMonitoring::TDynamicCounters> counters)
- : DynamicCounters(counters)
- {
- ActorMsgs_ = DynamicCounters->GetCounter("ActorMsgs", true);
- DirectMsgs_ = DynamicCounters->GetCounter("DirectMsgs", true);
- LevelRequests_ = DynamicCounters->GetCounter("LevelRequests", true);
- IgnoredMsgs_ = DynamicCounters->GetCounter("IgnoredMsgs", true);
- DroppedMsgs_ = DynamicCounters->GetCounter("DroppedMsgs", true);
-
- AlertMsgs_ = DynamicCounters->GetCounter("AlertMsgs", true);
- EmergMsgs_ = DynamicCounters->GetCounter("EmergMsgs", true);
- }
-
- ~TLoggerCounters() = default;
-
- void IncActorMsgs() override {
- ++*ActorMsgs_;
- }
- void IncDirectMsgs() override {
- ++*DirectMsgs_;
- }
- void IncLevelRequests() override {
- ++*LevelRequests_;
- }
- void IncIgnoredMsgs() override {
- ++*IgnoredMsgs_;
- }
- void IncAlertMsgs() override {
- ++*AlertMsgs_;
- }
- void IncEmergMsgs() override {
- ++*EmergMsgs_;
- }
- void IncDroppedMsgs() override {
- DroppedMsgs_->Inc();
- }
-
- void GetOutputHtml(IOutputStream& str) override {
- HTML(str) {
- DIV_CLASS("row") {
- DIV_CLASS("col-md-12") {
- TAG(TH4) {
- str << "Counters" << Endl;
- }
- DynamicCounters->OutputHtml(str);
- }
- }
- }
- }
-
-private:
- NMonitoring::TDynamicCounters::TCounterPtr ActorMsgs_;
- NMonitoring::TDynamicCounters::TCounterPtr DirectMsgs_;
- NMonitoring::TDynamicCounters::TCounterPtr LevelRequests_;
- NMonitoring::TDynamicCounters::TCounterPtr IgnoredMsgs_;
- NMonitoring::TDynamicCounters::TCounterPtr AlertMsgs_;
- NMonitoring::TDynamicCounters::TCounterPtr EmergMsgs_;
- // Dropped while the logger backend was unavailable
- NMonitoring::TDynamicCounters::TCounterPtr DroppedMsgs_;
-
- TIntrusivePtr<NMonitoring::TDynamicCounters> DynamicCounters;
-};
-
-class TLoggerMetrics : public ILoggerMetrics {
-public:
- TLoggerMetrics(std::shared_ptr<NMonitoring::TMetricRegistry> metrics)
- : Metrics(metrics)
- {
- ActorMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.actor_msgs"}});
- DirectMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.direct_msgs"}});
- LevelRequests_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.level_requests"}});
- IgnoredMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.ignored_msgs"}});
- DroppedMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.dropped_msgs"}});
-
- AlertMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.alert_msgs"}});
- EmergMsgs_ = Metrics->Rate(NMonitoring::TLabels{{"sensor", "logger.emerg_msgs"}});
- }
-
- ~TLoggerMetrics() = default;
-
- void IncActorMsgs() override {
- ActorMsgs_->Inc();
- }
- void IncDirectMsgs() override {
- DirectMsgs_->Inc();
- }
- void IncLevelRequests() override {
- LevelRequests_->Inc();
- }
- void IncIgnoredMsgs() override {
- IgnoredMsgs_->Inc();
- }
- void IncAlertMsgs() override {
- AlertMsgs_->Inc();
- }
- void IncEmergMsgs() override {
- EmergMsgs_->Inc();
- }
- void IncDroppedMsgs() override {
- DroppedMsgs_->Inc();
- }
-
- void GetOutputHtml(IOutputStream& str) override {
- HTML(str) {
- DIV_CLASS("row") {
- DIV_CLASS("col-md-12") {
- TAG(TH4) {
- str << "Metrics" << Endl;
- }
- // TODO: Now, TMetricRegistry does not have the GetOutputHtml function
- }
- }
- }
- }
-
-private:
- NMonitoring::TRate* ActorMsgs_;
- NMonitoring::TRate* DirectMsgs_;
- NMonitoring::TRate* LevelRequests_;
- NMonitoring::TRate* IgnoredMsgs_;
- NMonitoring::TRate* AlertMsgs_;
- NMonitoring::TRate* EmergMsgs_;
- // Dropped while the logger backend was unavailable
- NMonitoring::TRate* DroppedMsgs_;
-
- std::shared_ptr<NMonitoring::TMetricRegistry> Metrics;
-};
-}
diff --git a/library/cpp/actors/core/log_settings.cpp b/library/cpp/actors/core/log_settings.cpp
deleted file mode 100644
index fafaf892eb..0000000000
--- a/library/cpp/actors/core/log_settings.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-#include "log_settings.h"
-
-#include <util/stream/str.h>
-
-namespace NActors {
- namespace NLog {
- TSettings::TSettings(const TActorId& loggerActorId, const EComponent loggerComponent,
- EComponent minVal, EComponent maxVal, EComponentToStringFunc func,
- EPriority defPriority, EPriority defSamplingPriority,
- ui32 defSamplingRate, ui64 timeThresholdMs, ui64 bufferSizeLimitBytes)
- : LoggerActorId(loggerActorId)
- , LoggerComponent(loggerComponent)
- , TimeThresholdMs(timeThresholdMs)
- , BufferSizeLimitBytes(bufferSizeLimitBytes)
- , AllowDrop(true)
- , ThrottleDelay(TDuration::MilliSeconds(100))
- , MinVal(0)
- , MaxVal(0)
- , Mask(0)
- , DefPriority(defPriority)
- , DefSamplingPriority(defSamplingPriority)
- , DefSamplingRate(defSamplingRate)
- , UseLocalTimestamps(false)
- , Format(PLAIN_FULL_FORMAT)
- , ShortHostName("")
- , ClusterName("")
- {
- Append(minVal, maxVal, func);
- }
-
- TSettings::TSettings(const TActorId& loggerActorId, const EComponent loggerComponent,
- EPriority defPriority, EPriority defSamplingPriority,
- ui32 defSamplingRate, ui64 timeThresholdMs, ui64 bufferSizeLimitBytes)
- : LoggerActorId(loggerActorId)
- , LoggerComponent(loggerComponent)
- , TimeThresholdMs(timeThresholdMs)
- , BufferSizeLimitBytes(bufferSizeLimitBytes)
- , AllowDrop(true)
- , ThrottleDelay(TDuration::MilliSeconds(100))
- , MinVal(0)
- , MaxVal(0)
- , Mask(0)
- , DefPriority(defPriority)
- , DefSamplingPriority(defSamplingPriority)
- , DefSamplingRate(defSamplingRate)
- , UseLocalTimestamps(false)
- , Format(PLAIN_FULL_FORMAT)
- , ShortHostName("")
- , ClusterName("")
- {
- }
-
- void TSettings::Append(EComponent minVal, EComponent maxVal, EComponentToStringFunc func) {
- Y_ABORT_UNLESS(minVal >= 0, "NLog::TSettings: minVal must be non-negative");
- Y_ABORT_UNLESS(maxVal > minVal, "NLog::TSettings: maxVal must be greater than minVal");
-
- // update bounds
- if (!MaxVal || minVal < MinVal) {
- MinVal = minVal;
- }
-
- if (!MaxVal || maxVal > MaxVal) {
- MaxVal = maxVal;
-
- // expand ComponentNames to the new bounds
- auto oldMask = Mask;
- Mask = PowerOf2Mask(MaxVal);
-
- TArrayHolder<TAtomic> oldComponentInfo(new TAtomic[Mask + 1]);
- ComponentInfo.Swap(oldComponentInfo);
- int startVal = oldMask ? oldMask + 1 : 0;
- for (int i = 0; i < startVal; i++) {
- AtomicSet(ComponentInfo[i], AtomicGet(oldComponentInfo[i]));
- }
-
- TComponentSettings defSetting(DefPriority, DefSamplingPriority, DefSamplingRate);
- for (int i = startVal; i < Mask + 1; i++) {
- AtomicSet(ComponentInfo[i], defSetting.Raw.Data);
- }
-
- ComponentNames.resize(Mask + 1);
- }
-
- // assign new names but validate if newly added members were not used before
- for (int i = minVal; i <= maxVal; i++) {
- Y_ABORT_UNLESS(!ComponentNames[i], "component name at %d already set: %s",
- i, ComponentNames[i].data());
- ComponentNames[i] = func(i);
- }
- }
-
- int TSettings::SetLevelImpl(
- const TString& name, bool isSampling,
- EPriority priority, EComponent component, TString& explanation) {
- TString titleName(name);
- titleName.to_title();
-
- // check priority
- if (!IsValidPriority(priority)) {
- TStringStream str;
- str << "Invalid " << name;
- explanation = str.Str();
- return 1;
- }
-
- if (component == InvalidComponent) {
- for (int i = 0; i < Mask + 1; i++) {
- TComponentSettings settings = AtomicGet(ComponentInfo[i]);
- if (isSampling) {
- settings.Raw.X.SamplingLevel = priority;
- } else {
- settings.Raw.X.Level = priority;
- }
- AtomicSet(ComponentInfo[i], settings.Raw.Data);
- }
-
- TStringStream str;
-
- str << titleName
- << " for all components has been changed to "
- << PriorityToString(EPrio(priority));
- explanation = str.Str();
- return 0;
- } else {
- if (!IsValidComponent(component)) {
- explanation = "Invalid component";
- return 1;
- }
- TComponentSettings settings = AtomicGet(ComponentInfo[component]);
- EPriority oldPriority;
- if (isSampling) {
- oldPriority = (EPriority)settings.Raw.X.SamplingLevel;
- settings.Raw.X.SamplingLevel = priority;
- } else {
- oldPriority = (EPriority)settings.Raw.X.Level;
- settings.Raw.X.Level = priority;
- }
- AtomicSet(ComponentInfo[component], settings.Raw.Data);
- TStringStream str;
- str << titleName << " for the component " << ComponentNames[component]
- << " has been changed from " << PriorityToString(EPrio(oldPriority))
- << " to " << PriorityToString(EPrio(priority));
- explanation = str.Str();
- return 0;
- }
- }
-
- int TSettings::SetLevel(EPriority priority, EComponent component, TString& explanation) {
- return SetLevelImpl("priority", false,
- priority, component, explanation);
- }
-
- int TSettings::SetSamplingLevel(EPriority priority, EComponent component, TString& explanation) {
- return SetLevelImpl("sampling priority", true,
- priority, component, explanation);
- }
-
- int TSettings::SetSamplingRate(ui32 sampling, EComponent component, TString& explanation) {
- if (component == InvalidComponent) {
- for (int i = 0; i < Mask + 1; i++) {
- TComponentSettings settings = AtomicGet(ComponentInfo[i]);
- settings.Raw.X.SamplingRate = sampling;
- AtomicSet(ComponentInfo[i], settings.Raw.Data);
- }
- TStringStream str;
- str << "Sampling rate for all components has been changed to " << sampling;
- explanation = str.Str();
- } else {
- if (!IsValidComponent(component)) {
- explanation = "Invalid component";
- return 1;
- }
- TComponentSettings settings = AtomicGet(ComponentInfo[component]);
- ui32 oldSampling = settings.Raw.X.SamplingRate;
- settings.Raw.X.SamplingRate = sampling;
- AtomicSet(ComponentInfo[component], settings.Raw.Data);
- TStringStream str;
- str << "Sampling rate for the component " << ComponentNames[component]
- << " has been changed from " << oldSampling
- << " to " << sampling;
- explanation = str.Str();
- }
- return 0;
- }
-
- int TSettings::PowerOf2Mask(int val) {
- int mask = 1;
- while ((val & mask) != val) {
- mask <<= 1;
- mask |= 1;
- }
- return mask;
- }
-
- bool TSettings::IsValidPriority(EPriority priority) {
- return priority == PRI_EMERG || priority == PRI_ALERT ||
- priority == PRI_CRIT || priority == PRI_ERROR ||
- priority == PRI_WARN || priority == PRI_NOTICE ||
- priority == PRI_INFO || priority == PRI_DEBUG || priority == PRI_TRACE;
- }
-
- bool TSettings::IsValidComponent(EComponent component) {
- return (MinVal <= component) && (component <= MaxVal) && !ComponentNames[component].empty();
- }
-
- void TSettings::SetAllowDrop(bool val) {
- AllowDrop = val;
- }
-
- void TSettings::SetThrottleDelay(TDuration value) {
- ThrottleDelay = value;
- }
-
- void TSettings::SetUseLocalTimestamps(bool value) {
- UseLocalTimestamps = value;
- }
-
- EComponent TSettings::FindComponent(const TStringBuf& componentName) const {
- if (componentName.empty())
- return InvalidComponent;
-
- for (EComponent component = MinVal; component <= MaxVal; ++component) {
- if (ComponentNames[component] == componentName)
- return component;
- }
-
- return InvalidComponent;
- }
-
- }
-
-}
diff --git a/library/cpp/actors/core/log_settings.h b/library/cpp/actors/core/log_settings.h
deleted file mode 100644
index f62f55c200..0000000000
--- a/library/cpp/actors/core/log_settings.h
+++ /dev/null
@@ -1,175 +0,0 @@
-#pragma once
-
-#include "log_iface.h"
-#include <util/generic/vector.h>
-#include <util/digest/murmur.h>
-#include <util/random/easy.h>
-
-namespace NActors {
- namespace NLog {
- inline const char* PriorityToString(EPrio priority) {
- switch (priority) {
- case EPrio::Emerg:
- return "EMERG";
- case EPrio::Alert:
- return "ALERT";
- case EPrio::Crit:
- return "CRIT";
- case EPrio::Error:
- return "ERROR";
- case EPrio::Warn:
- return "WARN";
- case EPrio::Notice:
- return "NOTICE";
- case EPrio::Info:
- return "INFO";
- case EPrio::Debug:
- return "DEBUG";
- case EPrio::Trace:
- return "TRACE";
- default:
- return "UNKNOWN";
- }
- }
-
- // You can structure your program to have multiple logical components.
- // In this case you can set different log priorities for different
- // components. And you can change component's priority while system
- // is running. Suspect a component has a bug? Turn DEBUG priority level on
- // for this component.
- static const int InvalidComponent = -1;
-
- // Functions converts EComponent id to string
- using EComponentToStringFunc = std::function<const TString&(EComponent)>;
-
- // Log settings
- struct TComponentSettings {
- union {
- struct {
- ui32 SamplingRate;
- ui8 SamplingLevel;
- ui8 Level;
- } X;
-
- ui64 Data;
- } Raw;
-
- TComponentSettings(TAtomicBase data) {
- Raw.Data = (ui64)data;
- }
-
- TComponentSettings(ui8 level, ui8 samplingLevel, ui32 samplingRate) {
- Raw.X.Level = level;
- Raw.X.SamplingLevel = samplingLevel;
- Raw.X.SamplingRate = samplingRate;
- }
- };
-
- struct TSettings: public TThrRefBase {
- public:
- TActorId LoggerActorId;
- EComponent LoggerComponent;
- ui64 TimeThresholdMs;
- ui64 BufferSizeLimitBytes;
- bool AllowDrop;
- TDuration ThrottleDelay;
- TArrayHolder<TAtomic> ComponentInfo;
- TVector<TString> ComponentNames;
- EComponent MinVal;
- EComponent MaxVal;
- EComponent Mask;
- EPriority DefPriority;
- EPriority DefSamplingPriority;
- ui32 DefSamplingRate;
- bool UseLocalTimestamps;
-
- enum ELogFormat {
- PLAIN_FULL_FORMAT,
- PLAIN_SHORT_FORMAT,
- JSON_FORMAT
- };
- ELogFormat Format;
- TString ShortHostName;
- TString ClusterName;
- TString MessagePrefix;
-
- // The best way to provide minVal, maxVal and func is to have
- // protobuf enumeration of components. In this case protoc
- // automatically generates YOURTYPE_MIN, YOURTYPE_MAX and
- // YOURTYPE_Name for you.
- TSettings(const TActorId& loggerActorId, const EComponent loggerComponent,
- EComponent minVal, EComponent maxVal, EComponentToStringFunc func,
- EPriority defPriority, EPriority defSamplingPriority = PRI_DEBUG,
- ui32 defSamplingRate = 0, ui64 timeThresholdMs = 1000, ui64 bufferSizeLimitBytes = 1024 * 1024 * 300);
-
- TSettings(const TActorId& loggerActorId, const EComponent loggerComponent,
- EPriority defPriority, EPriority defSamplingPriority = PRI_DEBUG,
- ui32 defSamplingRate = 0, ui64 timeThresholdMs = 1000, ui64 bufferSizeLimitBytes = 1024 * 1024 * 300);
-
- void Append(EComponent minVal, EComponent maxVal, EComponentToStringFunc func);
-
- template <typename T>
- void Append(T minVal, T maxVal, const TString& (*func)(T)) {
- Append(
- static_cast<EComponent>(minVal),
- static_cast<EComponent>(maxVal),
- [func](EComponent c) -> const TString& {
- return func(static_cast<T>(c));
- }
- );
- }
-
- inline bool Satisfies(EPriority priority, EComponent component, ui64 sampleBy = 0) const {
- // by using Mask we don't get outside of array boundaries
- TComponentSettings settings = GetComponentSettings(component);
- if (priority > settings.Raw.X.Level) {
- if (priority > settings.Raw.X.SamplingLevel) {
- return false; // priority > both levels ==> do not log
- }
- // 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;
- return (samplingValue % samplingRate == 0);
- } else {
- // sampling rate not set ==> do not log
- return false;
- }
- } else {
- // priority <= log level ==> log
- return true;
- }
- }
-
- inline TComponentSettings GetComponentSettings(EComponent component) const {
- Y_DEBUG_ABORT_UNLESS((component & Mask) == component);
- // by using Mask we don't get outside of array boundaries
- return TComponentSettings(AtomicGet(ComponentInfo[component & Mask]));
- }
-
- const char* ComponentName(EComponent component) const {
- Y_DEBUG_ABORT_UNLESS((component & Mask) == component);
- return ComponentNames[component & Mask].data();
- }
-
- int SetLevel(EPriority priority, EComponent component, TString& explanation);
- int SetSamplingLevel(EPriority priority, EComponent component, TString& explanation);
- int SetSamplingRate(ui32 sampling, EComponent component, TString& explanation);
- EComponent FindComponent(const TStringBuf& componentName) const;
- static int PowerOf2Mask(int val);
- static bool IsValidPriority(EPriority priority);
- bool IsValidComponent(EComponent component);
- void SetAllowDrop(bool val);
- void SetThrottleDelay(TDuration value);
- void SetUseLocalTimestamps(bool value);
-
- private:
- int SetLevelImpl(
- const TString& name, bool isSampling,
- EPriority priority, EComponent component, TString& explanation);
- };
-
- }
-
-}
diff --git a/library/cpp/actors/core/log_ut.cpp b/library/cpp/actors/core/log_ut.cpp
deleted file mode 100644
index 995e3c4121..0000000000
--- a/library/cpp/actors/core/log_ut.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-#include "log.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <library/cpp/actors/testlib/test_runtime.h>
-
-using namespace NMonitoring;
-using namespace NActors;
-using namespace NActors::NLog;
-
-namespace {
- const TString& ServiceToString(int) {
- static const TString FAKE{"FAKE"};
- return FAKE;
- }
-
- TIntrusivePtr<TSettings> DefaultSettings() {
- auto loggerId = TActorId{0, "Logger"};
- auto s = MakeIntrusive<TSettings>(loggerId, 0, EPriority::PRI_TRACE);
- s->SetAllowDrop(false);
- s->Append(0, 1, ServiceToString);
- return s;
- }
-
- TIntrusivePtr<TSettings> DroppingSettings(ui64 timeThresholdMs) {
- auto loggerId = TActorId{0, "Logger"};
- auto s = MakeIntrusive<TSettings>(
- loggerId,
- 0,
- EPriority::PRI_TRACE,
- EPriority::PRI_DEBUG,
- (ui32)0,
- timeThresholdMs,
- (ui64)0);
- s->Append(0, 1, ServiceToString);
- return s;
- }
-
- TIntrusivePtr<TSettings> BufferSettings(ui64 bufferSizeLimitBytes) {
- auto loggerId = TActorId{0, "Logger"};
- auto s = MakeIntrusive<TSettings>(
- loggerId,
- 0,
- EPriority::PRI_TRACE,
- EPriority::PRI_DEBUG,
- (ui32)0,
- (ui32)0,
- bufferSizeLimitBytes);
- s->Append(0, 1, ServiceToString);
- s->SetAllowDrop(true);
- return s;
- }
-
- TIntrusivePtr<TSettings> NoBufferSettings() {
- return BufferSettings(0);
- }
-
- class TMockBackend: public TLogBackend {
- public:
- using TWriteImpl = std::function<void(const TLogRecord&)>;
- using TReopenImpl = std::function<void()>;
-
- static void REOPEN_NOP() { }
-
- TMockBackend(TWriteImpl writeImpl, TReopenImpl reopenImpl = REOPEN_NOP)
- : WriteImpl_{writeImpl}
- , ReopenImpl_{reopenImpl}
- {
- }
-
- void WriteData(const TLogRecord& r) override {
- WriteImpl_(r);
- }
-
- void ReopenLog() override { }
-
- void SetWriteImpl(TWriteImpl writeImpl) {
- WriteImpl_ = writeImpl;
- }
-
- private:
- TWriteImpl WriteImpl_;
- TReopenImpl ReopenImpl_;
- };
-
- void ThrowAlways(const TLogRecord&) {
- ythrow yexception();
- };
-
- struct TFixture {
- TFixture(
- TIntrusivePtr<TSettings> settings,
- TMockBackend::TWriteImpl writeImpl = ThrowAlways)
- {
- Runtime.Initialize();
- LogBackend.reset(new TMockBackend{writeImpl});
- LoggerActor = Runtime.Register(new TLoggerActor{settings, LogBackend, Counters});
- Runtime.SetScheduledEventFilter([] (auto&&, auto&&, auto&&, auto) {
- return false;
- });
- }
-
- TFixture(TMockBackend::TWriteImpl writeImpl = ThrowAlways)
- : TFixture(DefaultSettings(), writeImpl)
- {}
-
- void WriteLog() {
- Runtime.Send(new IEventHandle{LoggerActor, {}, new TEvLog(TInstant::Zero(), TLevel{EPrio::Emerg}, 0, "foo")});
- }
-
- void WriteLog(TInstant ts, EPrio prio = EPrio::Emerg, TString msg = "foo") {
- Runtime.Send(new IEventHandle{LoggerActor, {}, new TEvLog(ts, TLevel{prio}, 0, msg)});
- }
-
- void FlushLogBuffer() {
- Runtime.Send(new IEventHandle{LoggerActor, {}, new TFlushLogBuffer()});
- }
-
- void Wakeup() {
- Runtime.Send(new IEventHandle{LoggerActor, {}, new TEvents::TEvWakeup});
- }
-
- TIntrusivePtr<TDynamicCounters> Counters{MakeIntrusive<TDynamicCounters>()};
- std::shared_ptr<TMockBackend> LogBackend;
- TActorId LoggerActor;
- TTestActorRuntimeBase Runtime;
- };
-}
-
-
-Y_UNIT_TEST_SUITE(TLoggerActorTest) {
- Y_UNIT_TEST(NoCrashOnWriteFailure) {
- TFixture test;
- test.WriteLog();
- // everything is okay as long as we get here
- }
-
- Y_UNIT_TEST(SubsequentWritesAreIgnored) {
- size_t count{0};
- auto countWrites = [&count] (auto&& r) {
- count++;
- ThrowAlways(r);
- };
-
- TFixture test{countWrites};
- test.WriteLog();
- UNIT_ASSERT_VALUES_EQUAL(count, 1);
-
- // at this point we should have started dropping messages
- for (auto i = 0; i < 5; ++i) {
- test.WriteLog();
- }
-
- UNIT_ASSERT_VALUES_EQUAL(count, 1);
- }
-
- Y_UNIT_TEST(LoggerCanRecover) {
- TFixture test;
- test.WriteLog();
-
- TVector<TString> messages;
- auto acceptWrites = [&] (const TLogRecord& r) {
- messages.emplace_back(r.Data, r.Len);
- };
-
- auto scheduled = test.Runtime.CaptureScheduledEvents();
- UNIT_ASSERT_VALUES_EQUAL(scheduled.size(), 1);
-
- test.LogBackend->SetWriteImpl(acceptWrites);
- test.Wakeup();
-
- const auto COUNT = 10;
- for (auto i = 0; i < COUNT; ++i) {
- test.WriteLog();
- }
-
- UNIT_ASSERT_VALUES_EQUAL(messages.size(), COUNT);
- }
-
- Y_UNIT_TEST(ShouldObeyTimeThresholdMsWhenOverloaded) {
- TFixture test{DroppingSettings(5000)};
-
- TVector<TString> messages;
- auto acceptWrites = [&] (const TLogRecord& r) {
- messages.emplace_back(r.Data, r.Len);
- };
-
- test.LogBackend->SetWriteImpl(acceptWrites);
- test.Wakeup();
-
- const auto COUNT = 11;
- for (auto i = 0; i < COUNT; ++i) {
- test.WriteLog();
- }
-
- UNIT_ASSERT_VALUES_EQUAL(messages.size(), COUNT);
-
- test.Runtime.AdvanceCurrentTime(TDuration::Seconds(20));
- auto now = test.Runtime.GetCurrentTime();
-
- test.WriteLog(now - TDuration::Seconds(5));
-
- UNIT_ASSERT_VALUES_EQUAL(messages.size(), COUNT + 1);
-
- test.WriteLog(now - TDuration::Seconds(6));
-
- UNIT_ASSERT_VALUES_EQUAL(messages.size(), COUNT + 1);
- }
-
- int BufferTest(TFixture &test, const int COUNT) {
- TVector<TString> messages;
- auto acceptWrites = [&] (const TLogRecord& r) {
- messages.emplace_back(r.Data, r.Len);
- };
-
- test.LogBackend->SetWriteImpl(acceptWrites);
- test.Wakeup();
- test.Runtime.AdvanceCurrentTime(TDuration::Days(1));
- auto now = test.Runtime.GetCurrentTime();
-
- for (auto i = 0; i < COUNT; ++i) {
- test.WriteLog(now - TDuration::Seconds(10), EPrio::Debug, std::to_string(i));
- }
-
- for (auto i = 0; i < COUNT; ++i) {
- test.FlushLogBuffer();
- }
-
- for (ui64 i = 0; i < messages.size(); ++i) {
- Cerr << messages[i] << Endl;
- }
-
- return messages.size();
- }
-
- Y_UNIT_TEST(ShouldUseLogBufferWhenOverloaded) {
- TFixture test{BufferSettings(1024 * 1024 * 300)};
- const auto LOG_COUNT = 100;
- auto outputLogSize = BufferTest(test, LOG_COUNT);
-
- UNIT_ASSERT_VALUES_EQUAL(outputLogSize, LOG_COUNT);
- }
-
- Y_UNIT_TEST(ShouldLoseLogsIfBufferZeroSize) {
- TFixture test{NoBufferSettings()};
- const auto LOG_COUNT = 100;
- auto outputLogSize = BufferTest(test, LOG_COUNT);
-
- UNIT_ASSERT(outputLogSize < LOG_COUNT);
- }
-}
diff --git a/library/cpp/actors/core/mailbox.cpp b/library/cpp/actors/core/mailbox.cpp
deleted file mode 100644
index d11ff9cbcb..0000000000
--- a/library/cpp/actors/core/mailbox.cpp
+++ /dev/null
@@ -1,590 +0,0 @@
-#include "mailbox.h"
-#include "actorsystem.h"
-#include "actor.h"
-
-#include <library/cpp/actors/util/datetime.h>
-
-#include <util/system/sanitizers.h>
-
-namespace NActors {
- TMailboxTable::TMailboxTable()
- : LastAllocatedLine(0)
- , AllocatedMailboxCount(0)
- , CachedSimpleMailboxes(0)
- , CachedRevolvingMailboxes(0)
- , CachedHTSwapMailboxes(0)
- , CachedReadAsFilledMailboxes(0)
- , CachedTinyReadAsFilledMailboxes(0)
- {
- memset((void*)Lines, 0, sizeof(Lines));
- }
-
- bool IsGoodForCleanup(const TMailboxHeader* header) {
- switch (AtomicLoad(&header->ExecutionState)) {
- case TMailboxHeader::TExecutionState::Inactive:
- case TMailboxHeader::TExecutionState::Scheduled:
- return true;
- case TMailboxHeader::TExecutionState::Leaving:
- case TMailboxHeader::TExecutionState::Executing:
- case TMailboxHeader::TExecutionState::LeavingMarked:
- return false;
- case TMailboxHeader::TExecutionState::Free:
- case TMailboxHeader::TExecutionState::FreeScheduled:
- return true;
- case TMailboxHeader::TExecutionState::FreeLeaving:
- case TMailboxHeader::TExecutionState::FreeExecuting:
- case TMailboxHeader::TExecutionState::FreeLeavingMarked:
- return false;
- default:
- Y_ABORT();
- }
- }
-
- template <typename TMailbox>
- void DestructMailboxLine(ui8* begin, ui8* end) {
- const ui32 sx = TMailbox::AlignedSize();
- for (ui8* x = begin; x + sx <= end; x += sx) {
- TMailbox* mailbox = reinterpret_cast<TMailbox*>(x);
- Y_ABORT_UNLESS(IsGoodForCleanup(mailbox));
- mailbox->ExecutionState = Max<ui32>();
- mailbox->~TMailbox();
- }
- }
-
- template <typename TMailbox>
- bool CleanupMailboxLine(ui8* begin, ui8* end) {
- const ui32 sx = TMailbox::AlignedSize();
- bool done = true;
- for (ui8* x = begin; x + sx <= end; x += sx) {
- TMailbox* mailbox = reinterpret_cast<TMailbox*>(x);
- Y_ABORT_UNLESS(IsGoodForCleanup(mailbox));
- done &= mailbox->CleanupActors() && mailbox->CleanupEvents();
- }
- return done;
- }
-
- TMailboxTable::~TMailboxTable() {
- // on cleanup we must traverse everything and free stuff
- for (ui32 i = 0; i < LastAllocatedLine; ++i) {
- if (TMailboxLineHeader* lineHeader = Lines[i]) {
- switch (lineHeader->MailboxType) {
- case TMailboxType::Simple:
- DestructMailboxLine<TSimpleMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize);
- break;
- case TMailboxType::Revolving:
- DestructMailboxLine<TRevolvingMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize);
- break;
- case TMailboxType::HTSwap:
- DestructMailboxLine<THTSwapMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize);
- break;
- case TMailboxType::ReadAsFilled:
- DestructMailboxLine<TReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize);
- break;
- case TMailboxType::TinyReadAsFilled:
- DestructMailboxLine<TTinyReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize);
- break;
- default:
- Y_ABORT();
- }
-
- lineHeader->~TMailboxLineHeader();
- free(lineHeader);
- Lines[i] = nullptr;
- }
- }
-
- while (MailboxCacheSimple.Pop(0))
- ;
- while (MailboxCacheRevolving.Pop(0))
- ;
- while (MailboxCacheHTSwap.Pop(0))
- ;
- while (MailboxCacheReadAsFilled.Pop(0))
- ;
- while (MailboxCacheTinyReadAsFilled.Pop(0))
- ;
- }
-
- bool TMailboxTable::Cleanup() {
- bool done = true;
- for (ui32 i = 0; i < LastAllocatedLine; ++i) {
- if (TMailboxLineHeader* lineHeader = Lines[i]) {
- switch (lineHeader->MailboxType) {
- case TMailboxType::Simple:
- done &= CleanupMailboxLine<TSimpleMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize);
- break;
- case TMailboxType::Revolving:
- done &= CleanupMailboxLine<TRevolvingMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize);
- break;
- case TMailboxType::HTSwap:
- done &= CleanupMailboxLine<THTSwapMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize);
- break;
- case TMailboxType::ReadAsFilled:
- done &= CleanupMailboxLine<TReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize);
- break;
- case TMailboxType::TinyReadAsFilled:
- done &= CleanupMailboxLine<TTinyReadAsFilledMailbox>((ui8*)lineHeader + 64, (ui8*)lineHeader + LineSize);
- break;
- default:
- Y_ABORT();
- }
- }
- }
- return done;
- }
-
- TMailboxHeader* TMailboxTable::Get(ui32 hint) {
- // get line
- const ui32 lineIndex = (hint & LineIndexMask) >> LineIndexShift;
- const ui32 lineHint = hint & LineHintMask;
-
- Y_ABORT_UNLESS((lineIndex < MaxLines) && (lineHint < LineSize / 64));
- if (lineHint == 0)
- return nullptr;
-
- if (TMailboxLineHeader* const x = AtomicLoad(Lines + lineIndex)) {
- switch (x->MailboxType) {
- case TMailboxType::Simple:
- return TSimpleMailbox::Get(lineHint, x);
- case TMailboxType::Revolving:
- return TRevolvingMailbox::Get(lineHint, x);
- case TMailboxType::HTSwap:
- return THTSwapMailbox::Get(lineHint, x);
- case TMailboxType::ReadAsFilled:
- return TReadAsFilledMailbox::Get(lineHint, x);
- case TMailboxType::TinyReadAsFilled:
- return TTinyReadAsFilledMailbox::Get(lineHint, x);
- default:
- Y_DEBUG_ABORT_UNLESS(false);
- break;
- }
- }
-
- return nullptr;
- }
-
- template <TMailboxTable::TEPScheduleActivationFunction EPSpecificScheduleActivation>
- bool TMailboxTable::GenericSendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool) {
- const TActorId& recipient = ev->GetRecipientRewrite();
- const ui32 hint = recipient.Hint();
-
- // copy-paste from Get to avoid duplicated type-switches
- const ui32 lineIndex = (hint & LineIndexMask) >> LineIndexShift;
- const ui32 lineHint = hint & LineHintMask;
-
- Y_ABORT_UNLESS((lineIndex < MaxLines) && (lineHint < LineSize / 64));
- if (lineHint == 0)
- return false;
-
- if (TMailboxLineHeader* const x = AtomicLoad(Lines + lineIndex)) {
- switch (x->MailboxType) {
- case TMailboxType::Simple: {
- TSimpleMailbox* const mailbox = TSimpleMailbox::Get(lineHint, x);
- mailbox->Push(recipient.LocalId());
-#if (!defined(_tsan_enabled_))
- Y_DEBUG_ABORT_UNLESS(mailbox->Type == (ui32)x->MailboxType);
-#endif
- mailbox->Queue.Push(ev.Release());
- if (mailbox->MarkForSchedule()) {
- RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast());
- (executorPool->*EPSpecificScheduleActivation)(hint);
- }
- }
- return true;
- case TMailboxType::Revolving: {
- // The actorid could be stale and coming from a different machine. If local process has restarted than
- // the stale actorid coming from a remote machine might be referencing an actor with simple mailbox
- // which is smaller than revolving mailbox. In this cases 'lineHint' index might be greater than actual
- // array size. Normally its ok to store stale event to other actor's valid mailbox beacuse Receive will
- // compare receiver actor id and discard stale event. But in this case we should discard the event right away
- // instead of trying to enque it to a mailbox at invalid address.
- // NOTE: lineHint is 1-based
- static_assert(TSimpleMailbox::AlignedSize() <= TRevolvingMailbox::AlignedSize(),
- "We expect that one line can store more simple mailboxes than revolving mailboxes");
- if (lineHint > TRevolvingMailbox::MaxMailboxesInLine())
- return false;
-
- TRevolvingMailbox* const mailbox = TRevolvingMailbox::Get(lineHint, x);
- mailbox->Push(recipient.LocalId());
-#if (!defined(_tsan_enabled_))
- Y_DEBUG_ABORT_UNLESS(mailbox->Type == (ui32)x->MailboxType);
-#endif
- mailbox->QueueWriter.Push(ev.Release());
- if (mailbox->MarkForSchedule()) {
- RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast());
- (executorPool->*EPSpecificScheduleActivation)(hint);
- }
- }
- return true;
- case TMailboxType::HTSwap: {
- THTSwapMailbox* const mailbox = THTSwapMailbox::Get(lineHint, x);
- mailbox->Push(recipient.LocalId());
-#if (!defined(_tsan_enabled_))
- Y_DEBUG_ABORT_UNLESS(mailbox->Type == (ui32)x->MailboxType);
-#endif
- mailbox->Queue.Push(ev.Release());
- if (mailbox->MarkForSchedule()) {
- RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast());
- (executorPool->*EPSpecificScheduleActivation)(hint);
- }
- }
- return true;
- case TMailboxType::ReadAsFilled: {
- if (lineHint > TReadAsFilledMailbox::MaxMailboxesInLine())
- return false;
-
- TReadAsFilledMailbox* const mailbox = TReadAsFilledMailbox::Get(lineHint, x);
- mailbox->Push(recipient.LocalId());
-#if (!defined(_tsan_enabled_))
- Y_DEBUG_ABORT_UNLESS(mailbox->Type == (ui32)x->MailboxType);
-#endif
- mailbox->Queue.Push(ev.Release());
- if (mailbox->MarkForSchedule()) {
- RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast());
- (executorPool->*EPSpecificScheduleActivation)(hint);
- }
- }
- return true;
- case TMailboxType::TinyReadAsFilled: {
- if (lineHint > TTinyReadAsFilledMailbox::MaxMailboxesInLine())
- return false;
-
- TTinyReadAsFilledMailbox* const mailbox = TTinyReadAsFilledMailbox::Get(lineHint, x);
- mailbox->Push(recipient.LocalId());
-#if (!defined(_tsan_enabled_))
- Y_DEBUG_ABORT_UNLESS(mailbox->Type == (ui32)x->MailboxType);
-#endif
- mailbox->Queue.Push(ev.Release());
- if (mailbox->MarkForSchedule()) {
- RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast());
- (executorPool->*EPSpecificScheduleActivation)(hint);
- }
- }
- return true;
- default:
- Y_ABORT("unknown mailbox type");
- }
- }
-
- return false;
- }
-
- ui32 TMailboxTable::AllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter) {
- ui32 x = TryAllocateMailbox(type, revolvingCounter);
- if (x == 0)
- x = AllocateNewLine(type);
- return x;
- }
-
- ui32 TMailboxTable::TryAllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter) {
- switch (type) {
- case TMailboxType::Simple:
- do {
- if (ui32 ret = MailboxCacheSimple.Pop(revolvingCounter)) {
- AtomicDecrement(CachedSimpleMailboxes);
- return ret;
- }
- } while (AtomicGet(CachedSimpleMailboxes) > (MailboxCacheSimple.Concurrency * 512));
- return 0;
- case TMailboxType::Revolving:
- do {
- if (ui32 ret = MailboxCacheRevolving.Pop(revolvingCounter)) {
- AtomicDecrement(CachedRevolvingMailboxes);
- return ret;
- }
- } while (AtomicGet(CachedRevolvingMailboxes) > (MailboxCacheRevolving.Concurrency * 512));
- return 0;
- case TMailboxType::HTSwap:
- do {
- if (ui32 ret = MailboxCacheHTSwap.Pop(revolvingCounter)) {
- AtomicDecrement(CachedHTSwapMailboxes);
- return ret;
- }
- } while (AtomicGet(CachedHTSwapMailboxes) > (MailboxCacheHTSwap.Concurrency * 512));
- return 0;
- case TMailboxType::ReadAsFilled:
- do {
- if (ui32 ret = MailboxCacheReadAsFilled.Pop(revolvingCounter)) {
- AtomicDecrement(CachedReadAsFilledMailboxes);
- return ret;
- }
- } while (AtomicGet(CachedReadAsFilledMailboxes) > (MailboxCacheReadAsFilled.Concurrency * 512));
- return 0;
- case TMailboxType::TinyReadAsFilled:
- do {
- if (ui32 ret = MailboxCacheTinyReadAsFilled.Pop(revolvingCounter)) {
- AtomicDecrement(CachedTinyReadAsFilledMailboxes);
- return ret;
- }
- } while (AtomicGet(CachedTinyReadAsFilledMailboxes) > (MailboxCacheTinyReadAsFilled.Concurrency * 512));
- return 0;
- default:
- Y_ABORT("Unknown mailbox type");
- }
- }
-
-
- template
- bool TMailboxTable::GenericSendTo<&IExecutorPool::ScheduleActivation>(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool);
- template
- bool TMailboxTable::GenericSendTo<&IExecutorPool::SpecificScheduleActivation>(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool);
-
- void TMailboxTable::ReclaimMailbox(TMailboxType::EType type, ui32 hint, ui64 revolvingCounter) {
- if (hint != 0) {
- switch (type) {
- case TMailboxType::Simple:
- MailboxCacheSimple.Push(hint, revolvingCounter);
- AtomicIncrement(CachedSimpleMailboxes);
- break;
- case TMailboxType::Revolving:
- MailboxCacheRevolving.Push(hint, revolvingCounter);
- AtomicIncrement(CachedRevolvingMailboxes);
- break;
- case TMailboxType::HTSwap:
- MailboxCacheHTSwap.Push(hint, revolvingCounter);
- AtomicIncrement(CachedHTSwapMailboxes);
- break;
- case TMailboxType::ReadAsFilled:
- MailboxCacheReadAsFilled.Push(hint, revolvingCounter);
- AtomicIncrement(CachedReadAsFilledMailboxes);
- break;
- case TMailboxType::TinyReadAsFilled:
- MailboxCacheTinyReadAsFilled.Push(hint, revolvingCounter);
- AtomicIncrement(CachedTinyReadAsFilledMailboxes);
- break;
- default:
- Y_ABORT();
- }
- }
- }
-
- TMailboxHeader::TMailboxHeader(TMailboxType::EType type)
- : ExecutionState(TExecutionState::Free)
- , Reserved(0)
- , Type(type)
- , ActorPack(TMailboxActorPack::Simple)
- , Knobs(0)
- {
- ActorsInfo.Simple.ActorId = 0;
- ActorsInfo.Simple.Actor = nullptr;
- }
-
- TMailboxHeader::~TMailboxHeader() {
- CleanupActors();
- }
-
- bool TMailboxHeader::CleanupActors() {
- bool done = true;
- switch (ActorPack) {
- case TMailboxActorPack::Simple: {
- if (ActorsInfo.Simple.ActorId != 0) {
- delete ActorsInfo.Simple.Actor;
- done = false;
- }
- break;
- }
- case TMailboxActorPack::Map: {
- for (auto& [actorId, actor] : *ActorsInfo.Map.ActorsMap) {
- delete actor;
- }
- delete ActorsInfo.Map.ActorsMap;
- done = false;
- break;
- }
- case TMailboxActorPack::Array: {
- for (ui64 i = 0; i < ActorsInfo.Array.ActorsCount; ++i) {
- delete ActorsInfo.Array.ActorsArray->Actors[i].Actor;
- }
- delete ActorsInfo.Array.ActorsArray;
- done = false;
- break;
- }
- }
- ActorPack = TMailboxActorPack::Simple;
- ActorsInfo.Simple.ActorId = 0;
- ActorsInfo.Simple.Actor = nullptr;
- return done;
- }
-
- std::pair<ui32, ui32> TMailboxHeader::CountMailboxEvents(ui64 localActorId, ui32 maxTraverse) {
- switch (Type) {
- case TMailboxType::Simple:
- return static_cast<TMailboxTable::TSimpleMailbox*>(this)->CountSimpleMailboxEvents(localActorId, maxTraverse);
- case TMailboxType::Revolving:
- return static_cast<TMailboxTable::TRevolvingMailbox*>(this)->CountRevolvingMailboxEvents(localActorId, maxTraverse);
- default:
- return {0, 0};
- }
- }
-
- TMailboxUsageImpl<true>::~TMailboxUsageImpl() {
- while (auto *e = PendingEventQueue.Pop()) {
- delete e;
- }
- }
-
- void TMailboxUsageImpl<true>::Push(ui64 localId) {
- PendingEventQueue.Push(new TPendingEvent{localId, GetCycleCountFast()});
- }
-
- void TMailboxUsageImpl<true>::ProcessEvents(TMailboxHeader *mailbox) {
- while (std::unique_ptr<TPendingEvent> e{PendingEventQueue.Pop()}) {
- if (IActor *actor = mailbox->FindActor(e->LocalId)) {
- actor->OnEnqueueEvent(e->Timestamp);
- }
- }
- }
-
- TMailboxTable::TSimpleMailbox::TSimpleMailbox()
- : TMailboxHeader(TMailboxType::Simple)
- , ScheduleMoment(0)
- {
- }
-
- TMailboxTable::TSimpleMailbox::~TSimpleMailbox() {
- CleanupEvents();
- }
-
- bool TMailboxTable::TSimpleMailbox::CleanupEvents() {
- const bool done = (Queue.Head() == nullptr);
- while (IEventHandle* ev = Queue.Pop())
- delete ev;
- return done;
- }
-
- std::pair<ui32, ui32> TMailboxTable::TSimpleMailbox::CountSimpleMailboxEvents(ui64 localActorId, ui32 maxTraverse) {
- ui32 local = 0;
- ui32 total = 0;
-
- auto it = Queue.ReadIterator();
- while (IEventHandle* x = it.Next()) {
- ++total;
- if (x->GetRecipientRewrite().LocalId() == localActorId)
- ++local;
- if (total >= maxTraverse)
- break;
- }
-
- return std::make_pair(local, total);
- }
-
- TMailboxTable::TRevolvingMailbox::TRevolvingMailbox()
- : TMailboxHeader(TMailboxType::Revolving)
- , QueueWriter(QueueReader)
- , Reserved1(0)
- , Reserved2(0)
- , ScheduleMoment(0)
- {
- }
-
- TMailboxTable::TRevolvingMailbox::~TRevolvingMailbox() {
- CleanupEvents();
- }
-
- bool TMailboxTable::TRevolvingMailbox::CleanupEvents() {
- const bool done = (QueueReader.Head() == nullptr);
- while (IEventHandle* ev = QueueReader.Pop())
- delete ev;
- return done;
- }
-
- std::pair<ui32, ui32> TMailboxTable::TRevolvingMailbox::CountRevolvingMailboxEvents(ui64 localActorId, ui32 maxTraverse) {
- ui32 local = 0;
- ui32 total = 0;
-
- auto it = QueueReader.Iterator();
-
- while (IEventHandle* x = it.Next()) {
- ++total;
- if (x->GetRecipientRewrite().LocalId() == localActorId)
- ++local;
- if (total >= maxTraverse)
- break;
- }
-
- return std::make_pair(local, total);
- }
-
- template <typename T>
- static ui32 InitNewLine(ui8* x, ui8* end) {
- const ui32 sx = T::AlignedSize();
-
- for (ui32 index = 1; x + sx <= end; x += sx, ++index)
- ::new (x) T();
-
- return sx;
- }
-
- ui32 TMailboxTable::AllocateNewLine(TMailboxType::EType type) {
- ui8* ptr = (ui8*)malloc(LineSize);
- ui8* end = ptr + LineSize;
-
- const ui32 lineIndex = (ui32)AtomicIncrement(LastAllocatedLine) - 1;
- const ui32 lineIndexMask = (lineIndex << LineIndexShift) & LineIndexMask;
-
- // first 64 bytes is TMailboxLineHeader
- TMailboxLineHeader* header = ::new (ptr) TMailboxLineHeader(type, lineIndex);
-
- ui8* x = ptr + 64;
- ui32 sx = 0;
- TMailboxCache* cache = nullptr;
- TAtomic* counter = nullptr;
-
- switch (type) {
- case TMailboxType::Simple:
- sx = InitNewLine<TSimpleMailbox>(x, end);
- cache = &MailboxCacheSimple;
- counter = &CachedSimpleMailboxes;
- break;
- case TMailboxType::Revolving:
- sx = InitNewLine<TRevolvingMailbox>(x, end);
- cache = &MailboxCacheRevolving;
- counter = &CachedRevolvingMailboxes;
- break;
- case TMailboxType::HTSwap:
- sx = InitNewLine<THTSwapMailbox>(x, end);
- cache = &MailboxCacheHTSwap;
- counter = &CachedHTSwapMailboxes;
- break;
- case TMailboxType::ReadAsFilled:
- sx = InitNewLine<TReadAsFilledMailbox>(x, end);
- cache = &MailboxCacheReadAsFilled;
- counter = &CachedReadAsFilledMailboxes;
- break;
- case TMailboxType::TinyReadAsFilled:
- sx = InitNewLine<TTinyReadAsFilledMailbox>(x, end);
- cache = &MailboxCacheTinyReadAsFilled;
- counter = &CachedTinyReadAsFilledMailboxes;
- break;
- default:
- Y_ABORT();
- }
-
- AtomicStore(Lines + lineIndex, header);
-
- ui32 ret = lineIndexMask | 1;
-
- ui32 index = 2;
- for (ui32 endIndex = LineSize / sx; index != endIndex;) {
- const ui32 bufSize = 8;
- ui32 buf[bufSize];
- ui32 bufIndex;
- for (bufIndex = 0; index != endIndex && bufIndex != bufSize; ++bufIndex, ++index)
- buf[bufIndex] = lineIndexMask | index;
- cache->PushBulk(buf, bufIndex, index);
- AtomicAdd(*counter, bufIndex);
- }
-
- AtomicAdd(AllocatedMailboxCount, index - 1);
-
- return ret;
- }
-
- bool TMailboxTable::SendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool) {
- return GenericSendTo<&IExecutorPool::ScheduleActivation>(ev, executorPool);
- }
-
- bool TMailboxTable::SpecificSendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool) {
- return GenericSendTo<&IExecutorPool::SpecificScheduleActivation>(ev, executorPool);
- }
-}
diff --git a/library/cpp/actors/core/mailbox.h b/library/cpp/actors/core/mailbox.h
deleted file mode 100644
index 4697dedcfd..0000000000
--- a/library/cpp/actors/core/mailbox.h
+++ /dev/null
@@ -1,571 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include "event.h"
-#include "executor_pool.h"
-#include "mailbox_queue_simple.h"
-#include "mailbox_queue_revolving.h"
-#include <library/cpp/actors/util/unordered_cache.h>
-#include <library/cpp/threading/queue/mpsc_htswap.h>
-#include <library/cpp/threading/queue/mpsc_read_as_filled.h>
-#include <util/generic/hash.h>
-#include <util/system/hp_timer.h>
-#include <util/generic/ptr.h>
-// TODO: clean all broken arcadia atomic stuff and replace with intrinsics
-
-namespace NActors {
- class IActor;
- class IExecutorPool;
-
- const ui64 ARRAY_CAPACITY = 8;
-
- // structure of hint:
- // 1 bit: is service or direct hint
- // 2 bits: pool index
- // 17 bits: line
- // 12 bits: index of mailbox inside of line
-
- struct TMailboxHeader;
-
- template<bool>
- struct TMailboxUsageImpl {
- void Push(ui64 /*localId*/) {}
- void ProcessEvents(TMailboxHeader* /*mailbox*/) {}
- };
-
- template<>
- struct TMailboxUsageImpl<true> {
- struct TPendingEvent {
- ui64 LocalId;
- ui64 Timestamp;
- };
- NThreading::TReadAsFilledQueue<TPendingEvent> PendingEventQueue;
-
- ~TMailboxUsageImpl();
- void Push(ui64 localId);
- void ProcessEvents(TMailboxHeader *mailbox);
- };
-
- struct TMailboxHeader
- : TMailboxUsageImpl<ActorLibCollectUsageStats>
- {
- struct TMailboxActorPack {
- enum EType {
- Simple = 0,
- Array = 1,
- Map = 2
- };
- };
-
- using TActorMap = THashMap<ui64, IActor*>;
-
- struct TExecutionState {
- enum EState {
- // normal states
- Inactive = 0,
- Scheduled = 1,
- Leaving = 2,
- Executing = 3,
- LeavingMarked = 4,
- // states for free mailboxes (they can still be scheduled so we need duplicates)
- Free = 5,
- FreeScheduled = 6,
- FreeLeaving = 7,
- FreeExecuting = 8,
- FreeLeavingMarked = 9,
- };
- };
-
- volatile ui32 ExecutionState;
- ui32 Reserved : 4; // never changes, always zero
- ui32 Type : 4; // never changes
- ui32 ActorPack : 2;
- ui32 Knobs : 22;
-
- struct TActorPair {
- IActor *Actor;
- ui64 ActorId;
- };
-
- struct alignas(64) TActorArray {
- TActorPair Actors[ARRAY_CAPACITY];
- };
-
- union TActorsInfo {
- TActorPair Simple;
- struct {
- TActorArray* ActorsArray;
- ui64 ActorsCount;
- } Array;
- struct {
- TActorMap* ActorsMap;
- } Map;
- } ActorsInfo;
-
- TMailboxHeader(TMailboxType::EType type);
- ~TMailboxHeader();
-
- bool CleanupActors();
-
- // this interface is used exclusively by executor thread, so implementation is there
-
- bool MarkForSchedule(); // we put something in queue, check should we schedule?
-
- bool LockForExecution(); // we got activation, try to lock mailbox
- bool LockFromFree(); // try to claim mailbox from recycled (could fail if other thread process garbage)
-
- void UnlockFromExecution1(); // prepare for releasing lock
- bool UnlockFromExecution2(bool wouldReschedule); // proceed with releasing lock
- bool UnlockAsFree(bool wouldReschedule); // preceed with releasing lock, but mark as free one
-
- bool IsEmpty() const noexcept {
- 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;
- }
- }
-
- IActor* FindActor(ui64 localActorId) noexcept {
- switch (ActorPack) {
- case TMailboxActorPack::Simple: {
- if (ActorsInfo.Simple.ActorId == localActorId)
- return ActorsInfo.Simple.Actor;
- break;
- }
- case TMailboxActorPack::Map: {
- TActorMap::iterator it = ActorsInfo.Map.ActorsMap->find(localActorId);
- if (it != ActorsInfo.Map.ActorsMap->end())
- return it->second;
- break;
- }
- case TMailboxActorPack::Array: {
- for (ui64 i = 0; i < ActorsInfo.Array.ActorsCount; ++i) {
- if (ActorsInfo.Array.ActorsArray->Actors[i].ActorId == localActorId) {
- return ActorsInfo.Array.ActorsArray->Actors[i].Actor;
- }
- }
- break;
- }
- default:
- Y_ABORT();
- }
- return nullptr;
- }
-
- void AttachActor(ui64 localActorId, IActor* actor) noexcept {
- switch (ActorPack) {
- case TMailboxActorPack::Simple: {
- if (ActorsInfo.Simple.ActorId == 0) {
- ActorsInfo.Simple.ActorId = localActorId;
- ActorsInfo.Simple.Actor = actor;
- return;
- } else {
- auto ar = new TActorArray;
- ar->Actors[0] = ActorsInfo.Simple;
- ar->Actors[1] = TActorPair{actor, localActorId};
- ActorsInfo.Array.ActorsCount = 2;
- ActorPack = TMailboxActorPack::Array;
- ActorsInfo.Array.ActorsArray = ar;
- }
- break;
- }
- case TMailboxActorPack::Map: {
- ActorsInfo.Map.ActorsMap->insert(TActorMap::value_type(localActorId, actor));
- break;
- }
- case TMailboxActorPack::Array: {
- if (ActorsInfo.Array.ActorsCount == ARRAY_CAPACITY) {
- TActorMap* mp = new TActorMap();
- for (ui64 i = 0; i < ARRAY_CAPACITY; ++i) {
- mp->emplace(ActorsInfo.Array.ActorsArray->Actors[i].ActorId, ActorsInfo.Array.ActorsArray->Actors[i].Actor);
- }
- mp->emplace(localActorId, actor);
- ActorPack = TMailboxActorPack::Map;
- ActorsInfo.Array.ActorsCount = 0;
- delete ActorsInfo.Array.ActorsArray;
- ActorsInfo.Map.ActorsMap = mp;
- } else {
- ActorsInfo.Array.ActorsArray->Actors[ActorsInfo.Array.ActorsCount++] = TActorPair{actor, localActorId};
- }
- break;
- }
- default:
- Y_ABORT();
- }
- }
-
- IActor* DetachActor(ui64 localActorId) noexcept {
- Y_DEBUG_ABORT_UNLESS(FindActor(localActorId) != nullptr);
-
- IActor* actorToDestruct = nullptr;
-
- switch (ActorPack) {
- case TMailboxActorPack::Simple: {
- Y_ABORT_UNLESS(ActorsInfo.Simple.ActorId == localActorId);
- actorToDestruct = ActorsInfo.Simple.Actor;
-
- ActorsInfo.Simple.ActorId = 0;
- ActorsInfo.Simple.Actor = nullptr;
- break;
- }
- case TMailboxActorPack::Map: {
- TActorMap::iterator it = ActorsInfo.Map.ActorsMap->find(localActorId);
- Y_ABORT_UNLESS(it != ActorsInfo.Map.ActorsMap->end());
-
- actorToDestruct = it->second;
- ActorsInfo.Map.ActorsMap->erase(it);
-
- if (ActorsInfo.Map.ActorsMap->size() == ARRAY_CAPACITY) {
- auto ar = new TActorArray;
- ui64 i = 0;
- for (auto& [actorId, actor] : *ActorsInfo.Map.ActorsMap) {
- ar->Actors[i++] = TActorPair{actor, actorId};
- }
- delete ActorsInfo.Map.ActorsMap;
- ActorPack = TMailboxActorPack::Array;
- ActorsInfo.Array.ActorsArray = ar;
- ActorsInfo.Array.ActorsCount = ARRAY_CAPACITY;
- }
- break;
- }
- case TMailboxActorPack::Array: {
- bool found = false;
- for (ui64 i = 0; i < ActorsInfo.Array.ActorsCount; ++i) {
- if (ActorsInfo.Array.ActorsArray->Actors[i].ActorId == localActorId) {
- found = true;
- actorToDestruct = ActorsInfo.Array.ActorsArray->Actors[i].Actor;
- ActorsInfo.Array.ActorsArray->Actors[i] = ActorsInfo.Array.ActorsArray->Actors[ActorsInfo.Array.ActorsCount - 1];
- ActorsInfo.Array.ActorsCount -= 1;
- break;
- }
- }
- Y_ABORT_UNLESS(found);
-
- if (ActorsInfo.Array.ActorsCount == 1) {
- const TActorPair Actor = ActorsInfo.Array.ActorsArray->Actors[0];
- delete ActorsInfo.Array.ActorsArray;
- ActorPack = TMailboxActorPack::Simple;
- ActorsInfo.Simple = Actor;
- }
- break;
- }
- }
-
- return actorToDestruct;
- }
-
- std::pair<ui32, ui32> CountMailboxEvents(ui64 localActorId, ui32 maxTraverse);
- };
-
- class TMailboxTable : TNonCopyable {
- private:
- struct TMailboxLineHeader {
- const TMailboxType::EType MailboxType;
- const ui32 Index;
- // some more stuff in first cache line, then goes mailboxes
- ui8 Padding[52];
-
- TMailboxLineHeader(TMailboxType::EType type, ui32 index)
- : MailboxType(type)
- , Index(index)
- {
- }
- };
- static_assert(sizeof(TMailboxLineHeader) <= 64, "expect sizeof(TMailboxLineHeader) <= 64");
-
- constexpr static ui64 MaxLines = 131000; // somewhat less then 2^17.
- constexpr static ui64 LineSize = 262144; // 64 * 2^12.
-
- TAtomic LastAllocatedLine;
- TAtomic AllocatedMailboxCount;
-
- typedef TUnorderedCache<ui32, 512, 4> TMailboxCache;
- TMailboxCache MailboxCacheSimple;
- TAtomic CachedSimpleMailboxes;
- TMailboxCache MailboxCacheRevolving;
- TAtomic CachedRevolvingMailboxes;
- TMailboxCache MailboxCacheHTSwap;
- TAtomic CachedHTSwapMailboxes;
- TMailboxCache MailboxCacheReadAsFilled;
- TAtomic CachedReadAsFilledMailboxes;
- TMailboxCache MailboxCacheTinyReadAsFilled;
- TAtomic CachedTinyReadAsFilledMailboxes;
-
- // and here goes large chunk of lines
- // presented as array of static size to avoid sync on access
- TMailboxLineHeader* volatile Lines[MaxLines];
-
- ui32 AllocateNewLine(TMailboxType::EType type);
- ui32 TryAllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter);
-
- public:
- TMailboxTable();
- ~TMailboxTable();
-
- bool Cleanup(); // returns true if nothing found to destruct (so nothing new is possible to be created)
-
- static const ui32 LineIndexShift = 12;
- static const ui32 LineIndexMask = 0x1FFFFu << LineIndexShift;
- static const ui32 LineHintMask = 0xFFFu;
- static const ui32 PoolIndexShift = TActorId::PoolIndexShift;
- static const ui32 PoolIndexMask = TActorId::PoolIndexMask;
-
- static ui32 LineIndex(ui32 hint) {
- return ((hint & LineIndexMask) >> LineIndexShift);
- }
- static ui32 PoolIndex(ui32 hint) {
- return TActorId::PoolIndex(hint);
- }
-
- TMailboxHeader* Get(ui32 hint);
- ui32 AllocateMailbox(TMailboxType::EType type, ui64 revolvingCounter);
- void ReclaimMailbox(TMailboxType::EType type, ui32 hint, ui64 revolvingCounter);
- ui64 GetAllocatedMailboxCount() const {
- return RelaxedLoad(&AllocatedMailboxCount);
- }
-
- private:
- typedef void (IExecutorPool::*TEPScheduleActivationFunction)(ui32 activation);
-
- template <TEPScheduleActivationFunction EPSpecificScheduleActivation>
- bool GenericSendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool);
-
- public:
- bool SendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool);
- bool SpecificSendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool);
-
- struct TSimpleMailbox: public TMailboxHeader {
- // 4 bytes - state
- // 4 bytes - knobs
- // 8 bytes - actorid
- // 8 bytes - actor*
- TSimpleMailboxQueue<IEventHandle*, 64> Queue; // 24 + 8 bytes (body, lock)
- NHPTimer::STime ScheduleMoment;
-
- TSimpleMailbox();
- ~TSimpleMailbox();
-
- IEventHandle* Pop() {
- return Queue.Pop();
- }
- IEventHandle* Head() {
- return Queue.Head();
- }
-
- static TSimpleMailbox* Get(ui32 hint, void* line) {
- return (TSimpleMailbox*)((ui8*)line + 64 + (hint - 1) * AlignedSize()); //
- }
- static const TMailboxType::EType MailboxType = TMailboxType::Simple;
- constexpr static ui32 AlignedSize() {
- return ((sizeof(TSimpleMailbox) + 63) / 64) * 64;
- }
-
- std::pair<ui32, ui32> CountSimpleMailboxEvents(ui64 localActorId, ui32 maxTraverse);
- bool CleanupEvents();
- };
-
- struct TRevolvingMailbox: public TMailboxHeader {
- // 4 bytes - state
- // 4 bytes - knobs
- // 8 bytes - actorid
- // 8 bytes - actor*
- TRevolvingMailboxQueue<IEventHandle*, 3, 128>::TReader QueueReader; // 8 * 3 + 4 * 3 + (padding): 40 bytes
- // here goes next cache-line, so less writers<-> reader interference
- TRevolvingMailboxQueue<IEventHandle*, 3, 128>::TWriter QueueWriter; // 8 * 3 + 4 * 3 + 8 : 48 bytes
- ui32 Reserved1;
- ui32 Reserved2;
- NHPTimer::STime ScheduleMoment;
-
- TRevolvingMailbox();
- ~TRevolvingMailbox();
-
- IEventHandle* Pop() {
- return QueueReader.Pop();
- }
- IEventHandle* Head() {
- return QueueReader.Head();
- }
-
- static TRevolvingMailbox* Get(ui32 hint, void* line) {
- return (TRevolvingMailbox*)((ui8*)line + 64 + (hint - 1) * AlignedSize());
- }
-
- constexpr static ui64 MaxMailboxesInLine() {
- return (LineSize - 64) / AlignedSize();
- }
- static const TMailboxType::EType MailboxType = TMailboxType::Revolving;
- constexpr static ui32 AlignedSize() {
- return ((sizeof(TRevolvingMailbox) + 63) / 64) * 64;
- }
-
- std::pair<ui32, ui32> CountRevolvingMailboxEvents(ui64 localActorId, ui32 maxTraverse);
- bool CleanupEvents();
- };
-
- struct THTSwapMailbox: public TMailboxHeader {
- using TQueueType = NThreading::THTSwapQueue<IEventHandle*>;
-
- TQueueType Queue;
- NHPTimer::STime ScheduleMoment;
- char Padding_[16];
-
- THTSwapMailbox()
- : TMailboxHeader(TMailboxType::HTSwap)
- , ScheduleMoment(0)
- {
- }
-
- ~THTSwapMailbox() {
- CleanupEvents();
- }
-
- IEventHandle* Pop() {
- return Queue.Pop();
- }
-
- IEventHandle* Head() {
- return Queue.Peek();
- }
-
- static THTSwapMailbox* Get(ui32 hint, void* line) {
- return (THTSwapMailbox*)((ui8*)line + 64 + (hint - 1) * AlignedSize());
- }
-
- constexpr static ui64 MaxMailboxesInLine() {
- return (LineSize - 64) / AlignedSize();
- }
-
- static const TMailboxType::EType MailboxType = TMailboxType::HTSwap;
-
- constexpr static ui32 AlignedSize() {
- return ((sizeof(THTSwapMailbox) + 63) / 64) * 64;
- }
-
- bool CleanupEvents() {
- const bool done = (Queue.Peek() == nullptr);
- while (IEventHandle* ev = Queue.Pop())
- delete ev;
- return done;
- }
- };
-
- struct TReadAsFilledMailbox: public TMailboxHeader {
- using TQueueType = NThreading::TReadAsFilledQueue<IEventHandle>;
-
- TQueueType Queue;
- NHPTimer::STime ScheduleMoment;
- char Padding_[8];
-
- TReadAsFilledMailbox()
- : TMailboxHeader(TMailboxType::ReadAsFilled)
- , ScheduleMoment(0)
- {
- }
-
- ~TReadAsFilledMailbox() {
- CleanupEvents();
- }
-
- IEventHandle* Pop() {
- return Queue.Pop();
- }
-
- IEventHandle* Head() {
- return Queue.Peek();
- }
-
- static TReadAsFilledMailbox* Get(ui32 hint, void* line) {
- return (TReadAsFilledMailbox*)((ui8*)line + 64 + (hint - 1) * AlignedSize());
- }
-
- constexpr static ui64 MaxMailboxesInLine() {
- return (LineSize - 64) / AlignedSize();
- }
-
- static const TMailboxType::EType MailboxType =
- TMailboxType::ReadAsFilled;
-
- constexpr static ui32 AlignedSize() {
- return ((sizeof(TReadAsFilledMailbox) + 63) / 64) * 64;
- }
-
- bool CleanupEvents() {
- const bool done = (Queue.Peek() == nullptr);
- while (IEventHandle* ev = Queue.Pop())
- delete ev;
- return done;
- }
- };
-
- struct TTinyReadAsFilledMailbox: public TMailboxHeader {
- using TQueueType = NThreading::TReadAsFilledQueue<
- IEventHandle,
- NThreading::TRaFQueueBunchSize<4>>;
-
- TQueueType Queue;
- NHPTimer::STime ScheduleMoment;
- char Padding_[8];
-
- TTinyReadAsFilledMailbox()
- : TMailboxHeader(TMailboxType::TinyReadAsFilled)
- , ScheduleMoment(0)
- {
- }
-
- ~TTinyReadAsFilledMailbox() {
- CleanupEvents();
- }
-
- IEventHandle* Pop() {
- return Queue.Pop();
- }
-
- IEventHandle* Head() {
- return Queue.Peek();
- }
-
- static TTinyReadAsFilledMailbox* Get(ui32 hint, void* line) {
- return (TTinyReadAsFilledMailbox*)((ui8*)line + 64 + (hint - 1) * AlignedSize());
- }
-
- constexpr static ui64 MaxMailboxesInLine() {
- return (LineSize - 64) / AlignedSize();
- }
-
- static const TMailboxType::EType MailboxType =
- TMailboxType::TinyReadAsFilled;
-
- constexpr static ui32 AlignedSize() {
- return ((sizeof(TTinyReadAsFilledMailbox) + 63) / 64) * 64;
- }
-
- bool CleanupEvents() {
- const bool done = (Queue.Peek() == nullptr);
- while (IEventHandle* ev = Queue.Pop())
- delete ev;
- return done;
- }
- };
- };
-}
diff --git a/library/cpp/actors/core/mailbox_queue_revolving.h b/library/cpp/actors/core/mailbox_queue_revolving.h
deleted file mode 100644
index e1a25dd352..0000000000
--- a/library/cpp/actors/core/mailbox_queue_revolving.h
+++ /dev/null
@@ -1,214 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include <library/cpp/actors/util/queue_chunk.h>
-
-namespace NActors {
- // add some concurrency to basic queue to avoid hangs under contention (we pay with memory, so use only when really expect contention)
- // ordering: every completed push guarantied to seen before any not-yet-initiated push. parallel pushes could reorder (and that is natural for concurrent queues).
- // try to place reader/writer on different cache-lines to avoid congestion b/w reader and writers.
- // if strict ordering does not matter - look at TManyOneQueue.
-
- template <typename T, ui32 TWriteConcurrency = 3, ui32 TSize = 128>
- class TRevolvingMailboxQueue {
- static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value");
-
- struct TValTagPair {
- volatile T Value;
- volatile ui64 Tag;
- };
-
- typedef TQueueChunk<TValTagPair, TSize> TChunk;
-
- static_assert(sizeof(TAtomic) == sizeof(TChunk*), "expect sizeof(TAtomic) == sizeof(TChunk*)");
- static_assert(sizeof(TAtomic) == sizeof(ui64), "expect sizeof(TAtomic) == sizeof(ui64)");
-
- public:
- class TWriter;
-
- class TReader {
- TChunk* ReadFrom[TWriteConcurrency];
- ui32 ReadPosition[TWriteConcurrency];
-
- friend class TRevolvingMailboxQueue<T, TWriteConcurrency, TSize>::TWriter; // for access to ReadFrom in constructor
-
- bool ChunkHead(ui32 idx, ui64* tag, T* value) {
- TChunk* head = ReadFrom[idx];
- const ui32 pos = ReadPosition[idx];
- if (pos != TChunk::EntriesCount) {
- if (const T xval = AtomicLoad(&head->Entries[pos].Value)) {
- const ui64 xtag = head->Entries[pos].Tag;
- if (xtag < *tag) {
- *value = xval;
- *tag = xtag;
- return true;
- }
- }
- } else if (TChunk* next = AtomicLoad(&head->Next)) {
- ReadFrom[idx] = next;
- delete head;
- ReadPosition[idx] = 0;
- return ChunkHead(idx, tag, value);
- }
-
- return false;
- }
-
- T Head(bool pop) {
- ui64 tag = Max<ui64>();
- T ret = T{};
- ui32 idx = 0;
-
- for (ui32 i = 0; i < TWriteConcurrency; ++i)
- if (ChunkHead(i, &tag, &ret))
- idx = i;
-
- // w/o second pass we could reorder updates with 'already scanned' range
- if (ret) {
- for (ui32 i = 0; i < TWriteConcurrency; ++i)
- if (ChunkHead(i, &tag, &ret))
- idx = i;
- }
-
- if (pop && ret)
- ++ReadPosition[idx];
-
- return ret;
- }
-
- public:
- TReader() {
- for (ui32 i = 0; i != TWriteConcurrency; ++i) {
- ReadFrom[i] = new TChunk();
- ReadPosition[i] = 0;
- }
- }
-
- ~TReader() {
- Y_DEBUG_ABORT_UNLESS(Head() == 0);
- for (ui32 i = 0; i < TWriteConcurrency; ++i)
- delete ReadFrom[i];
- }
-
- T Pop() {
- return Head(true);
- }
-
- T Head() {
- return Head(false);
- }
-
- class TReadIterator {
- TChunk* ReadFrom[TWriteConcurrency];
- ui32 ReadPosition[TWriteConcurrency];
-
- bool ChunkHead(ui32 idx, ui64* tag, T* value) {
- TChunk* head = ReadFrom[idx];
- const ui32 pos = ReadPosition[idx];
- if (pos != TChunk::EntriesCount) {
- if (const T xval = AtomicLoad(&head->Entries[pos].Value)) {
- const ui64 xtag = head->Entries[pos].Tag;
- if (xtag < *tag) {
- *value = xval;
- *tag = xtag;
- return true;
- }
- }
- } else if (TChunk* next = AtomicLoad(&head->Next)) {
- ReadFrom[idx] = next;
- ReadPosition[idx] = 0;
- return ChunkHead(idx, tag, value);
- }
-
- return false;
- }
-
- public:
- TReadIterator(TChunk* const* readFrom, const ui32* readPosition) {
- memcpy(ReadFrom, readFrom, TWriteConcurrency * sizeof(TChunk*));
- memcpy(ReadPosition, readPosition, TWriteConcurrency * sizeof(ui32));
- }
-
- T Next() {
- ui64 tag = Max<ui64>();
- T ret = T{};
- ui32 idx = 0;
-
- for (ui32 i = 0; i < TWriteConcurrency; ++i)
- if (ChunkHead(i, &tag, &ret))
- idx = i;
-
- // w/o second pass we could reorder updates with 'already scanned' range
- if (ret) {
- for (ui32 i = 0; i < TWriteConcurrency; ++i)
- if (ChunkHead(i, &tag, &ret))
- idx = i;
- }
-
- if (ret)
- ++ReadPosition[idx];
-
- return ret;
- }
- };
-
- TReadIterator Iterator() const {
- return TReadIterator(ReadFrom, ReadPosition);
- }
- };
-
- class TWriter {
- TChunk* volatile WriteTo[TWriteConcurrency];
- volatile ui64 Tag;
- ui32 WritePosition[TWriteConcurrency];
-
- public:
- TWriter(const TReader& reader)
- : Tag(0)
- {
- for (ui32 i = 0; i != TWriteConcurrency; ++i) {
- WriteTo[i] = reader.ReadFrom[i];
- WritePosition[i] = 0;
- }
- }
-
- bool TryPush(T x) {
- Y_ABORT_UNLESS(x != 0);
-
- for (ui32 i = 0; i != TWriteConcurrency; ++i) {
- if (RelaxedLoad(&WriteTo[i]) != nullptr) {
- if (TChunk* writeTo = AtomicSwap(&WriteTo[i], nullptr)) {
- const ui64 nextTag = AtomicIncrement(Tag);
- Y_DEBUG_ABORT_UNLESS(nextTag < Max<ui64>());
- const ui32 writePosition = WritePosition[i];
- if (writePosition != TChunk::EntriesCount) {
- writeTo->Entries[writePosition].Tag = nextTag;
- AtomicStore(&writeTo->Entries[writePosition].Value, x);
- ++WritePosition[i];
- } else {
- TChunk* next = new TChunk();
- next->Entries[0].Tag = nextTag;
- next->Entries[0].Value = x;
- AtomicStore(&writeTo->Next, next);
- writeTo = next;
- WritePosition[i] = 1;
- }
- AtomicStore(WriteTo + i, writeTo);
- return true;
- }
- }
- }
- return false;
- }
-
- ui32 Push(T x) {
- ui32 spins = 0;
- while (!TryPush(x)) {
- ++spins;
- SpinLockPause();
- }
- return spins;
- }
- };
- };
-}
diff --git a/library/cpp/actors/core/mailbox_queue_simple.h b/library/cpp/actors/core/mailbox_queue_simple.h
deleted file mode 100644
index 2e44c21adb..0000000000
--- a/library/cpp/actors/core/mailbox_queue_simple.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include <library/cpp/actors/util/ticket_lock.h>
-#include <library/cpp/actors/util/queue_oneone_inplace.h>
-
-namespace NActors {
- // dead-simple one-one queue, based on serializability guaranties of x64 and ticket lock to ensure writer unicity.
- template <typename T, ui32 TSize>
- class TSimpleMailboxQueue {
- TOneOneQueueInplace<T, TSize> Queue;
- TTicketLock Lock;
-
- public:
- ui32 Push(T x) noexcept {
- const ui32 spins = Lock.Acquire();
- Queue.Push(x);
- Lock.Release();
- return spins;
- }
-
- T Head() {
- return Queue.Head();
- }
-
- T Pop() {
- return Queue.Pop();
- }
-
- typename TOneOneQueueInplace<T, TSize>::TReadIterator ReadIterator() {
- return Queue.Iterator();
- }
- };
-}
diff --git a/library/cpp/actors/core/mon.h b/library/cpp/actors/core/mon.h
deleted file mode 100644
index ba5debbd17..0000000000
--- a/library/cpp/actors/core/mon.h
+++ /dev/null
@@ -1,267 +0,0 @@
-#pragma once
-
-#include "events.h"
-#include "event_local.h"
-#include <library/cpp/monlib/service/monservice.h>
-#include <library/cpp/monlib/service/pages/mon_page.h>
-
-namespace NActors {
- namespace NMon {
- enum {
- HttpInfo = EventSpaceBegin(NActors::TEvents::ES_MON),
- HttpInfoRes,
- RemoteHttpInfo,
- RemoteHttpInfoRes,
- RemoteJsonInfoRes,
- RemoteBinaryInfoRes,
- End
- };
-
- static_assert(End < EventSpaceEnd(NActors::TEvents::ES_MON), "expect End < EventSpaceEnd(NActors::TEvents::ES_MON)");
-
- // request info from an actor in HTML format
- struct TEvHttpInfo: public NActors::TEventLocal<TEvHttpInfo, HttpInfo> {
- TEvHttpInfo(const NMonitoring::IMonHttpRequest& request, int subReqId = 0)
- : Request(request)
- , SubRequestId(subReqId)
- {
- }
-
- TEvHttpInfo(const NMonitoring::IMonHttpRequest& request, const TString& userToken)
- : Request(request)
- , UserToken(userToken)
- , SubRequestId(0)
- {
- }
-
- const NMonitoring::IMonHttpRequest& Request;
- TString UserToken; // built and serialized
- // SubRequestId != 0 means that we assemble reply from multiple parts and SubRequestId contains this part id
- int SubRequestId;
- };
-
- // base class for HTTP info response
- struct IEvHttpInfoRes: public NActors::TEventLocal<IEvHttpInfoRes, HttpInfoRes> {
- enum EContentType {
- Html,
- Custom,
- };
-
- IEvHttpInfoRes() {
- }
-
- virtual ~IEvHttpInfoRes() {
- }
-
- virtual void Output(IOutputStream& out) const = 0;
- virtual EContentType GetContentType() const = 0;
- };
-
- // Ready to output HTML in TString
- struct TEvHttpInfoRes: public IEvHttpInfoRes {
- TEvHttpInfoRes(const TString& answer, int subReqId = 0, EContentType contentType = Html)
- : Answer(answer)
- , SubRequestId(subReqId)
- , ContentType(contentType)
- {
- }
-
- void Output(IOutputStream& out) const override {
- out << Answer;
- }
-
- EContentType GetContentType() const override {
- return ContentType;
- }
-
- const TString Answer;
- const int SubRequestId;
- const EContentType ContentType;
- };
-
- struct TEvRemoteHttpInfo: public NActors::TEventBase<TEvRemoteHttpInfo, RemoteHttpInfo> {
- TEvRemoteHttpInfo() = default;
-
- TEvRemoteHttpInfo(const TString& query, HTTP_METHOD method = HTTP_METHOD_UNDEFINED)
- : Query(query)
- , Method(method)
- {
- }
-
- TEvRemoteHttpInfo(NActorsProto::TRemoteHttpInfo info)
- : Query(MakeSerializedQuery(info))
- , ExtendedQuery(std::move(info))
- {}
-
- static TString MakeSerializedQuery(const NActorsProto::TRemoteHttpInfo& info) {
- TString s(1, '\0');
- const bool success = info.AppendToString(&s);
- Y_ABORT_UNLESS(success);
- return s;
- }
-
- TString Query;
- HTTP_METHOD Method = HTTP_METHOD_UNDEFINED;
- std::optional<NActorsProto::TRemoteHttpInfo> ExtendedQuery;
-
- TString PathInfo() const {
- if (ExtendedQuery) {
- return ExtendedQuery->GetPath();
- } else {
- const size_t pos = Query.find('?');
- return (pos == TString::npos) ? TString() : Query.substr(0, pos);
- }
- }
-
- TCgiParameters Cgi() const {
- if (ExtendedQuery) {
- TCgiParameters params;
- for (const auto& kv : ExtendedQuery->GetQueryParams()) {
- params.emplace(kv.GetKey(), kv.GetValue());
- }
- return params;
- } else {
- const size_t pos = Query.find('?');
- return TCgiParameters((pos == TString::npos) ? TString() : Query.substr(pos + 1));
- }
- }
-
- HTTP_METHOD GetMethod() const {
- return ExtendedQuery ? static_cast<HTTP_METHOD>(ExtendedQuery->GetMethod()) : Method;
- }
-
- TString ToStringHeader() const override {
- return "TEvRemoteHttpInfo";
- }
-
- bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
- return serializer->WriteString(&Query);
- }
-
- ui32 CalculateSerializedSize() const override {
- return Query.size();
- }
-
- bool IsSerializable() const override {
- return true;
- }
-
- static IEventBase* Load(TEventSerializedData* bufs) {
- TString s = bufs->GetString();
- if (s.size() && s[0] == '\0') {
- TRope::TConstIterator iter = bufs->GetBeginIter();
- ui64 size = bufs->GetSize();
- iter += 1, --size; // skip '\0'
- TRopeStream stream(iter, size);
-
- auto res = std::make_unique<TEvRemoteHttpInfo>();
- res->Query = s;
- res->ExtendedQuery.emplace();
- const bool success = res->ExtendedQuery->ParseFromZeroCopyStream(&stream);
- Y_ABORT_UNLESS(success);
- return res.release();
- } else {
- return new TEvRemoteHttpInfo(s);
- }
- }
- };
-
- struct TEvRemoteHttpInfoRes: public NActors::TEventBase<TEvRemoteHttpInfoRes, RemoteHttpInfoRes> {
- TEvRemoteHttpInfoRes() {
- }
-
- TEvRemoteHttpInfoRes(const TString& html)
- : Html(html)
- {
- }
-
- TString Html;
-
- TString ToStringHeader() const override {
- return "TEvRemoteHttpInfoRes";
- }
-
- bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
- 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());
- }
- };
-
- struct TEvRemoteJsonInfoRes: public NActors::TEventBase<TEvRemoteJsonInfoRes, RemoteJsonInfoRes> {
- TEvRemoteJsonInfoRes() {
- }
-
- TEvRemoteJsonInfoRes(const TString& json)
- : Json(json)
- {
- }
-
- TString Json;
-
- TString ToStringHeader() const override {
- return "TEvRemoteJsonInfoRes";
- }
-
- bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
- 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());
- }
- };
-
- struct TEvRemoteBinaryInfoRes: public NActors::TEventBase<TEvRemoteBinaryInfoRes, RemoteBinaryInfoRes> {
- TEvRemoteBinaryInfoRes() {
- }
-
- TEvRemoteBinaryInfoRes(const TString& blob)
- : Blob(blob)
- {
- }
-
- TString Blob;
-
- TString ToStringHeader() const override {
- return "TEvRemoteBinaryInfoRes";
- }
-
- bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override {
- 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());
- }
- };
-
- }
-
-}
diff --git a/library/cpp/actors/core/mon_stats.h b/library/cpp/actors/core/mon_stats.h
deleted file mode 100644
index 4fb49d70c0..0000000000
--- a/library/cpp/actors/core/mon_stats.h
+++ /dev/null
@@ -1,191 +0,0 @@
-#pragma once
-
-#include "defs.h"
-//#include "actor.h"
-#include <library/cpp/actors/util/local_process_key.h>
-#include <library/cpp/monlib/metrics/histogram_snapshot.h>
-#include <util/system/hp_timer.h>
-
-namespace NActors {
- struct TLogHistogram : public NMonitoring::IHistogramSnapshot {
- TLogHistogram() {
- memset(Buckets, 0, sizeof(Buckets));
- }
-
- inline void Add(ui64 val, ui64 inc = 1) {
- size_t ind = 0;
-#if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 7
- asm volatile("" ::
- : "memory");
-#endif
- if (val > 1) {
- ind = GetValueBitCount(val - 1);
- }
-#if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 7
- asm volatile("" ::
- : "memory");
-#endif
- RelaxedStore(&TotalSamples, RelaxedLoad(&TotalSamples) + inc);
- RelaxedStore(&Buckets[ind], RelaxedLoad(&Buckets[ind]) + inc);
- }
-
- void Aggregate(const TLogHistogram& other) {
- const ui64 inc = RelaxedLoad(&other.TotalSamples);
- RelaxedStore(&TotalSamples, RelaxedLoad(&TotalSamples) + inc);
- for (size_t i = 0; i < Y_ARRAY_SIZE(Buckets); ++i) {
- Buckets[i] += RelaxedLoad(&other.Buckets[i]);
- }
- }
-
- // IHistogramSnapshot
- ui32 Count() const override {
- return Y_ARRAY_SIZE(Buckets);
- }
-
- NMonitoring::TBucketBound UpperBound(ui32 index) const override {
- Y_ASSERT(index < Y_ARRAY_SIZE(Buckets));
- if (index == 0) {
- return 1;
- }
- return NMonitoring::TBucketBound(1ull << (index - 1)) * 2.0;
- }
-
- NMonitoring::TBucketValue Value(ui32 index) const override {
- Y_ASSERT(index < Y_ARRAY_SIZE(Buckets));
- return Buckets[index];
- }
-
- ui64 TotalSamples = 0;
- ui64 Buckets[65];
- };
-
- struct TExecutorPoolStats {
- ui64 MaxUtilizationTime = 0;
- ui64 IncreasingThreadsByNeedyState = 0;
- ui64 IncreasingThreadsByExchange = 0;
- ui64 DecreasingThreadsByStarvedState = 0;
- ui64 DecreasingThreadsByHoggishState = 0;
- ui64 DecreasingThreadsByExchange = 0;
- i64 MaxConsumedCpuUs = 0;
- i64 MinConsumedCpuUs = 0;
- i64 MaxBookedCpuUs = 0;
- i64 MinBookedCpuUs = 0;
- double SpinningTimeUs = 0;
- double SpinThresholdUs = 0;
- i16 WrongWakenedThreadCount = 0;
- i16 CurrentThreadCount = 0;
- i16 PotentialMaxThreadCount = 0;
- i16 DefaultThreadCount = 0;
- i16 MaxThreadCount = 0;
- bool IsNeedy = false;
- bool IsStarved = false;
- bool IsHoggish = false;
- };
-
- struct TExecutorThreadStats {
- ui64 SentEvents = 0;
- ui64 ReceivedEvents = 0;
- ui64 PreemptedEvents = 0; // Number of events experienced hard preemption
- ui64 NonDeliveredEvents = 0;
- ui64 EmptyMailboxActivation = 0;
- ui64 CpuUs = 0; // microseconds thread was executing on CPU (accounts for preemtion)
- ui64 SafeElapsedTicks = 0;
- ui64 WorstActivationTimeUs = 0;
- NHPTimer::STime ElapsedTicks = 0;
- NHPTimer::STime ParkedTicks = 0;
- NHPTimer::STime BlockedTicks = 0;
- TLogHistogram ActivationTimeHistogram;
- TLogHistogram EventDeliveryTimeHistogram;
- TLogHistogram EventProcessingCountHistogram;
- TLogHistogram EventProcessingTimeHistogram;
- TVector<NHPTimer::STime> ElapsedTicksByActivity;
- TVector<ui64> ReceivedEventsByActivity;
- TVector<i64> ActorsAliveByActivity; // the sum should be positive, but per-thread might be negative
- TVector<ui64> ScheduledEventsByActivity;
- TVector<ui64> StuckActorsByActivity;
- TVector<std::array<ui64, 10>> UsageByActivity;
- ui64 PoolActorRegistrations = 0;
- ui64 PoolDestroyedActors = 0;
- ui64 PoolAllocatedMailboxes = 0;
- ui64 MailboxPushedOutByTailSending = 0;
- ui64 MailboxPushedOutBySoftPreemption = 0;
- ui64 MailboxPushedOutByTime = 0;
- ui64 MailboxPushedOutByEventCount = 0;
- ui64 NotEnoughCpuExecutions = 0;
-
- TExecutorThreadStats() // must be not empty as 0 used as default
- : ElapsedTicksByActivity(TLocalProcessKeyStateIndexLimiter::GetMaxKeysCount())
- , ReceivedEventsByActivity(TLocalProcessKeyStateIndexLimiter::GetMaxKeysCount())
- , ActorsAliveByActivity(TLocalProcessKeyStateIndexLimiter::GetMaxKeysCount())
- , ScheduledEventsByActivity(TLocalProcessKeyStateIndexLimiter::GetMaxKeysCount())
- , StuckActorsByActivity(TLocalProcessKeyStateIndexLimiter::GetMaxKeysCount())
- , UsageByActivity(TLocalProcessKeyStateIndexLimiter::GetMaxKeysCount())
- {}
-
- template <typename T>
- static void AggregateOne(TVector<T>& self, const TVector<T>& other) {
- const size_t selfSize = self.size();
- const size_t otherSize = other.size();
- if (selfSize < otherSize)
- self.resize(otherSize);
- for (size_t at = 0; at < otherSize; ++at)
- self[at] += RelaxedLoad(&other[at]);
- }
-
- void Aggregate(const TExecutorThreadStats& other) {
- SentEvents += RelaxedLoad(&other.SentEvents);
- ReceivedEvents += RelaxedLoad(&other.ReceivedEvents);
- PreemptedEvents += RelaxedLoad(&other.PreemptedEvents);
- NonDeliveredEvents += RelaxedLoad(&other.NonDeliveredEvents);
- EmptyMailboxActivation += RelaxedLoad(&other.EmptyMailboxActivation);
- CpuUs += RelaxedLoad(&other.CpuUs);
- SafeElapsedTicks += RelaxedLoad(&other.SafeElapsedTicks);
- RelaxedStore(
- &WorstActivationTimeUs,
- std::max(RelaxedLoad(&WorstActivationTimeUs), RelaxedLoad(&other.WorstActivationTimeUs)));
- ElapsedTicks += RelaxedLoad(&other.ElapsedTicks);
- ParkedTicks += RelaxedLoad(&other.ParkedTicks);
- BlockedTicks += RelaxedLoad(&other.BlockedTicks);
- MailboxPushedOutByTailSending += RelaxedLoad(&other.MailboxPushedOutByTailSending);
- MailboxPushedOutBySoftPreemption += RelaxedLoad(&other.MailboxPushedOutBySoftPreemption);
- MailboxPushedOutByTime += RelaxedLoad(&other.MailboxPushedOutByTime);
- MailboxPushedOutByEventCount += RelaxedLoad(&other.MailboxPushedOutByEventCount);
- NotEnoughCpuExecutions += RelaxedLoad(&other.NotEnoughCpuExecutions);
-
- ActivationTimeHistogram.Aggregate(other.ActivationTimeHistogram);
- EventDeliveryTimeHistogram.Aggregate(other.EventDeliveryTimeHistogram);
- EventProcessingCountHistogram.Aggregate(other.EventProcessingCountHistogram);
- EventProcessingTimeHistogram.Aggregate(other.EventProcessingTimeHistogram);
-
- AggregateOne(ElapsedTicksByActivity, other.ElapsedTicksByActivity);
- AggregateOne(ReceivedEventsByActivity, other.ReceivedEventsByActivity);
- AggregateOne(ActorsAliveByActivity, other.ActorsAliveByActivity);
- AggregateOne(ScheduledEventsByActivity, other.ScheduledEventsByActivity);
- AggregateOne(StuckActorsByActivity, other.StuckActorsByActivity);
-
- if (UsageByActivity.size() < other.UsageByActivity.size()) {
- UsageByActivity.resize(other.UsageByActivity.size());
- }
- for (size_t i = 0; i < UsageByActivity.size(); ++i) {
- for (size_t j = 0; j < 10; ++j) {
- UsageByActivity[i][j] += RelaxedLoad(&other.UsageByActivity[i][j]);
- }
- }
-
- RelaxedStore(
- &PoolActorRegistrations,
- std::max(RelaxedLoad(&PoolActorRegistrations), RelaxedLoad(&other.PoolActorRegistrations)));
- RelaxedStore(
- &PoolDestroyedActors,
- std::max(RelaxedLoad(&PoolDestroyedActors), RelaxedLoad(&other.PoolDestroyedActors)));
- RelaxedStore(
- &PoolAllocatedMailboxes,
- std::max(RelaxedLoad(&PoolAllocatedMailboxes), RelaxedLoad(&other.PoolAllocatedMailboxes)));
- }
-
- size_t MaxActivityType() const {
- return ActorsAliveByActivity.size();
- }
- };
-
-}
diff --git a/library/cpp/actors/core/mon_ut.cpp b/library/cpp/actors/core/mon_ut.cpp
deleted file mode 100644
index fa5dbbe71e..0000000000
--- a/library/cpp/actors/core/mon_ut.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/actors/core/mon.h>
-
-using namespace NActors;
-using namespace NMon;
-
-Y_UNIT_TEST_SUITE(ActorSystemMon) {
- Y_UNIT_TEST(SerializeEv) {
- NActorsProto::TRemoteHttpInfo info;
- info.SetPath("hello");
-
- auto ev = std::make_unique<TEvRemoteHttpInfo>(info);
- UNIT_ASSERT(ev->ExtendedQuery);
- UNIT_ASSERT_VALUES_EQUAL(ev->ExtendedQuery->GetPath(), info.GetPath());
- UNIT_ASSERT_VALUES_EQUAL(ev->PathInfo(), info.GetPath());
-
- TAllocChunkSerializer ser;
- const bool success = ev->SerializeToArcadiaStream(&ser);
- Y_ABORT_UNLESS(success);
- auto buffer = ser.Release(ev->CreateSerializationInfo());
- std::unique_ptr<TEvRemoteHttpInfo> restored(dynamic_cast<TEvRemoteHttpInfo*>(TEvRemoteHttpInfo::Load(buffer.Get())));
- UNIT_ASSERT(restored->Query == ev->Query);
- UNIT_ASSERT(restored->Query.size());
- UNIT_ASSERT(restored->Query[0] == '\0');
- UNIT_ASSERT(restored->ExtendedQuery);
- UNIT_ASSERT_VALUES_EQUAL(restored->ExtendedQuery->GetPath(), ev->ExtendedQuery->GetPath());
- UNIT_ASSERT_VALUES_EQUAL(restored->PathInfo(), ev->PathInfo());
- }
-}
diff --git a/library/cpp/actors/core/monotonic.cpp b/library/cpp/actors/core/monotonic.cpp
deleted file mode 100644
index 581d80d849..0000000000
--- a/library/cpp/actors/core/monotonic.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "monotonic.h"
diff --git a/library/cpp/actors/core/monotonic.h b/library/cpp/actors/core/monotonic.h
deleted file mode 100644
index 2c53785390..0000000000
--- a/library/cpp/actors/core/monotonic.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include <util/datetime/base.h>
-#include <library/cpp/time_provider/monotonic.h>
-
-namespace NActors {
-
-using NMonotonic::GetMonotonicMicroSeconds;
-
-using TMonotonic = NMonotonic::TMonotonic;
-
-} // namespace NActors
diff --git a/library/cpp/actors/core/monotonic_provider.cpp b/library/cpp/actors/core/monotonic_provider.cpp
deleted file mode 100644
index f8d91a4eec..0000000000
--- a/library/cpp/actors/core/monotonic_provider.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "monotonic_provider.h"
diff --git a/library/cpp/actors/core/monotonic_provider.h b/library/cpp/actors/core/monotonic_provider.h
deleted file mode 100644
index befe4f7b90..0000000000
--- a/library/cpp/actors/core/monotonic_provider.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#pragma once
-
-#include <library/cpp/time_provider/monotonic_provider.h>
-
-namespace NActors {
-
-using IMonotonicTimeProvider = NMonotonic::IMonotonicTimeProvider;
-
-using NMonotonic::CreateDefaultMonotonicTimeProvider;
-
-} // namespace NActors
diff --git a/library/cpp/actors/core/performance_ut.cpp b/library/cpp/actors/core/performance_ut.cpp
deleted file mode 100644
index 3c1a0ed143..0000000000
--- a/library/cpp/actors/core/performance_ut.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-#include "actorsystem.h"
-#include "av_bootstrapped.h"
-#include "actor_virtual.h"
-#include "actor_bootstrapped.h"
-#include "config.h"
-#include "event_local.h"
-#include "executor_pool_basic.h"
-#include "executor_pool_io.h"
-#include "executor_pool_base.h"
-#include "scheduler_basic.h"
-
-#include <library/cpp/actors/testlib/test_runtime.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NActors;
-
-Y_UNIT_TEST_SUITE(ActorSystemPerformance) {
-
- class TQueueTestRuntime {
- std::unique_ptr<TActorSystem> ActorSystem;
- public:
- TQueueTestRuntime() {
- auto setup = MakeHolder<TActorSystemSetup>();
- setup->NodeId = 1;
- setup->ExecutorsCount = 2;
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[2]);
- setup->Executors[0].Reset(new TBasicExecutorPool(0, 4, 20));
- setup->Executors[1].Reset(new TIOExecutorPool(1, 10));
-
- setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(512, 100)));
-
- ActorSystem.reset(new TActorSystem{ setup });
- }
-
- void Start() {
- ActorSystem->Start();
- }
-
- void Stop() {
- ActorSystem->Stop();
- ActorSystem.reset();
- }
-
- void Send(std::unique_ptr<IEventHandle>&& ev) {
- ActorSystem->Send(ev.release());
- }
-
- void Register(IActor* actor) {
- ActorSystem->Register(actor);
- }
- };
-
- enum EEvSubscribe {
- EvDolbExecute,
- EvEnd
- };
-
- class TEventLocalDolbilkaOld: public NActors::TEventLocal<TEventLocalDolbilkaOld, EvDolbExecute> {
- public:
-
- };
-
- class TDolbilkaCommon {
- protected:
- ui32 Counter = 0;
- ui32 CounterLimit = 10000000;
- const TInstant Start = Now();
- std::atomic<TDuration> Duration;
- std::atomic<bool> Ready = false;
- public:
- bool MakeStep() {
- if (++Counter >= CounterLimit) {
- TDolbilkaCommon::Finish();
- return false;
- }
- return true;
- }
- TDuration GetDurationInProgress() const {
- return Now() - Start;
- }
- double GetOperationDuration() const {
- return 1.0 * Duration.load().MicroSeconds() / Counter * 1000;
- }
- void Finish() {
- if (!Ready.exchange(true)) {
- Duration = GetDurationInProgress();
- }
- }
- bool IsFinished() const {
- return Ready;
- }
- };
-
- class TDolbilkaOld: public TDolbilkaCommon, public NActors::TActorBootstrapped<TDolbilkaOld> {
- private:
- using TBase = NActors::TActorBootstrapped<TDolbilkaOld>;
- public:
-
- STFUNC(StateInit) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEventLocalDolbilkaOld, Handle);
- default:
- Y_ABORT_UNLESS(false);
- }
- }
-
- void Handle(TEventLocalDolbilkaOld::TPtr& /*ev*/, const TActorContext&) {
- if (MakeStep()) {
- Sender<TEventLocalDolbilkaOld>().SendTo(SelfId());
- }
- }
-
- void Bootstrap() {
- Become(&TThis::StateInit);
- Sender<TEventLocalDolbilkaOld>().SendTo(SelfId());
- }
- };
-
- class TDolbilkaNew;
- class TEventLocalDolbilkaNew: public NActors::TEventLocalForActor<TEventLocalDolbilkaNew, TDolbilkaNew> {
- public:
-
- };
-
- class TDolbilkaNew: public TDolbilkaCommon, public NActors::TActorAutoStart {
- private:
- using TBase = NActors::TActorAutoStart;
- protected:
- virtual void DoOnStart(const TActorId& /*senderActorId*/) override {
- Sender<TEventLocalDolbilkaNew>().SendTo(SelfId());
- }
-
- public:
- void ProcessEvent(NActors::TEventContext<TEventLocalDolbilkaNew>& /*ev*/) {
- if (MakeStep()) {
- Sender<TEventLocalDolbilkaNew>().SendTo(SelfId());
- }
- }
- };
-
- class IDolbilkaSimple {
- public:
- virtual ~IDolbilkaSimple() = default;
- virtual bool ProcessEvent() = 0;
- };
-
- class TDolbilkaSimple: public TDolbilkaCommon, public IDolbilkaSimple {
- private:
-// TMutex Mutex;
- public:
- virtual bool ProcessEvent() override {
-// TGuard<TMutex> g(Mutex);
- return MakeStep();
- }
- };
-
- Y_UNIT_TEST(PerfTest) {
- THolder<TQueueTestRuntime> runtime(new TQueueTestRuntime);
- runtime->Start();
- TDolbilkaNew* dNew = new TDolbilkaNew;
- runtime->Register(dNew);
- while (dNew->GetDurationInProgress() < TDuration::Seconds(1000) && !dNew->IsFinished()) {
- Sleep(TDuration::Seconds(1));
- }
- Y_ABORT_UNLESS(dNew->IsFinished());
- TDolbilkaOld* dOld = new TDolbilkaOld;
- runtime->Register(dOld);
- while (dOld->GetDurationInProgress() < TDuration::Seconds(1000) && !dOld->IsFinished()) {
- Sleep(TDuration::Seconds(1));
- }
- Y_ABORT_UNLESS(dOld->IsFinished());
- std::unique_ptr<TDolbilkaSimple> dSimple(new TDolbilkaSimple);
- IDolbilkaSimple* dSimpleIface = dSimple.get();
- while (dSimpleIface->ProcessEvent()) {
-
- }
- Cerr << "DURATION_OLD: " << 1.0 * dOld->GetOperationDuration() << "ns" << Endl;
- Cerr << "DURATION_NEW: " << 1.0 * dNew->GetOperationDuration() << "ns" << Endl;
- Cerr << "DURATION_SIMPLE: " << 1.0 * dSimple->GetOperationDuration() << "ns" << Endl;
-
- }
-}
diff --git a/library/cpp/actors/core/probes.cpp b/library/cpp/actors/core/probes.cpp
deleted file mode 100644
index 7ace83e102..0000000000
--- a/library/cpp/actors/core/probes.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "probes.h"
-
-#include "actorsystem.h"
-
-#include <util/string/builder.h>
-
-LWTRACE_DEFINE_PROVIDER(ACTORLIB_PROVIDER);
-
-namespace NActors {
- TVector<NLWTrace::TDashboard> LWTraceDashboards(TActorSystemSetup* setup) {
- TVector<NLWTrace::TDashboard> result;
-
- NLWTrace::TDashboard slowDash;
- ui32 pools = setup->GetExecutorsCount();
- size_t top = 30;
- slowDash.SetName("ActorSystem slow events");
- slowDash.SetDescription(TStringBuilder() << "TOP" << top << " slow event executions >1M cycles for every pool (refresh page to update)");
- for (ui32 pool = 0; pool < pools; pool++) {
- auto* row = slowDash.AddRows();
- auto* cell = row->AddCells();
- cell->SetTitle(TStringBuilder() << pool << ":" << setup->GetPoolName(pool));
- cell->SetUrl(TStringBuilder() << "?mode=log&id=.ACTORLIB_PROVIDER.SlowEvent.ppoolId=" << pool << "&s=eventMs&reverse=y&head=30");
- }
- result.push_back(slowDash);
-
- return result;
- }
-}
diff --git a/library/cpp/actors/core/probes.h b/library/cpp/actors/core/probes.h
deleted file mode 100644
index 531923b5ad..0000000000
--- a/library/cpp/actors/core/probes.h
+++ /dev/null
@@ -1,221 +0,0 @@
-#pragma once
-
-#include <library/cpp/lwtrace/all.h>
-#include <util/generic/vector.h>
-
-#define LWACTORID(x) (x).RawX1(), (x).RawX2(), (x).NodeId(), (x).PoolID()
-#define LWTYPE_ACTORID ui64, ui64, ui32, ui32
-#define LWNAME_ACTORID(n) n "Raw1", n "Raw2", n "NodeId", n "PoolId"
-
-#define ACTORLIB_PROVIDER(PROBE, EVENT, GROUPS, TYPES, NAMES) \
- PROBE(SlowEvent, GROUPS("ActorLibSlow"), \
- TYPES(ui32, double, TString, TString, TString), \
- NAMES("poolId", "eventMs", "eventType", "actorId", "actorType")) \
- PROBE(EventSlowDelivery, GROUPS("ActorLibSlow"), \
- TYPES(ui32, double, double, ui64, TString, TString, TString), \
- NAMES("poolId", "deliveryMs", "sinceActivationMs", "eventProcessedBefore", "eventType", "actorId", "actorType")) \
- PROBE(SlowActivation, GROUPS("ActorLibSlow"), \
- TYPES(ui32, double), \
- NAMES("poolId", "activationMs")) \
- PROBE(SlowRegisterNew, GROUPS("ActorLibSlow"), \
- TYPES(ui32, double), \
- NAMES("poolId", "registerNewMs")) \
- PROBE(SlowRegisterAdd, GROUPS("ActorLibSlow"), \
- TYPES(ui32, double), \
- NAMES("poolId", "registerAddMs")) \
- PROBE(MailboxPushedOutByTailSending, GROUPS("ActorLibMailbox", "ActorLibMailboxPushedOut"), \
- TYPES(ui32, TString, ui32, TDuration, ui64, TString, TString), \
- NAMES("poolId", "pool", "eventsProcessed", "procTimeMs", "workerId", "actorId", "actorType")) \
- PROBE(MailboxPushedOutBySoftPreemption, GROUPS("ActorLibMailbox", "ActorLibMailboxPushedOut"), \
- TYPES(ui32, TString, ui32, TDuration, ui64, TString, TString), \
- NAMES("poolId", "pool", "eventsProcessed", "procTimeMs", "workerId", "actorId", "actorType")) \
- PROBE(MailboxPushedOutByTime, GROUPS("ActorLibMailbox", "ActorLibMailboxPushedOut"), \
- TYPES(ui32, TString, ui32, TDuration, ui64, TString, TString), \
- NAMES("poolId", "pool", "eventsProcessed", "procTimeMs", "workerId", "actorId", "actorType")) \
- PROBE(MailboxPushedOutByEventCount, GROUPS("ActorLibMailbox", "ActorLibMailboxPushedOut"), \
- TYPES(ui32, TString, ui32, TDuration, ui64, TString, TString), \
- NAMES("poolId", "pool", "eventsProcessed", "procTimeMs", "workerId", "actorId", "actorType")) \
- PROBE(MailboxEmpty, GROUPS("ActorLibMailbox"), \
- TYPES(ui32, TString, ui32, TDuration, ui64, TString, TString), \
- NAMES("poolId", "pool", "eventsProcessed", "procTimeMs", "workerId", "actorId", "actorType")) \
- PROBE(ActivationBegin, GROUPS(), \
- TYPES(ui32, ui32, ui32, double), \
- NAMES("cpu", "poolId", "workerId", "expireMs")) \
- PROBE(ActivationEnd, GROUPS(), \
- TYPES(ui32, ui32, ui32), \
- NAMES("cpu", "poolId", "workerId")) \
- PROBE(ExecutorThreadStats, GROUPS("ActorLibStats"), \
- TYPES(ui32, TString, ui64, ui64, ui64, double, double), \
- NAMES("poolId", "pool", "workerId", "execCount", "readyActivationCount", "execMs", "nonExecMs")) \
- PROBE(SlowICReadLoopAdjustSize, GROUPS("ActorLibSlowIC"), \
- TYPES(double), \
- NAMES("icReadLoopAdjustSizeMs")) \
- PROBE(SlowICReadFromSocket, GROUPS("ActorLibSlowIC"), \
- TYPES(double), \
- NAMES("icReadFromSocketMs")) \
- PROBE(SlowICReadLoopSend, GROUPS("ActorLibSlowIC"), \
- TYPES(double), \
- NAMES("icReadLoopSendMs")) \
- PROBE(SlowICAllocPacketBuffer, GROUPS("ActorLibSlowIC"), \
- TYPES(ui32, double), \
- NAMES("peerId", "icAllocPacketBufferMs")) \
- PROBE(SlowICFillSendingBuffer, GROUPS("ActorLibSlowIC"), \
- TYPES(ui32, double), \
- NAMES("peerId", "icFillSendingBufferMs")) \
- PROBE(SlowICPushSentPackets, GROUPS("ActorLibSlowIC"), \
- TYPES(ui32, double), \
- NAMES("peerId", "icPushSentPacketsMs")) \
- PROBE(SlowICPushSendQueue, GROUPS("ActorLibSlowIC"), \
- TYPES(ui32, double), \
- NAMES("peerId", "icPushSendQueueMs")) \
- PROBE(SlowICWriteData, GROUPS("ActorLibSlowIC"), \
- TYPES(ui32, double), \
- 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", \
- "eventsInSendQueue", "eventSchedulingErrorUs")) \
- PROBE(ForwardEvent, GROUPS("Orbit", "InterconnectSessionTCP"), \
- TYPES(ui32, ui32, ui32, LWTYPE_ACTORID, LWTYPE_ACTORID, ui64, ui32), \
- NAMES("peerId", "type", "flags", LWNAME_ACTORID("r"), LWNAME_ACTORID("s"), \
- "cookie", "eventSerializedSize")) \
- PROBE(EnqueueEvent, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, ui64, TDuration, ui16, ui64, ui64), \
- NAMES("peerId", "numEventsInReadyChannels", "enqueueBlockedTotalMs", "channelId", "queueSizeInEvents", "queueSizeInBytes")) \
- PROBE(SerializeToPacketBegin, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, ui16, ui64), \
- NAMES("peerId", "channelId", "outputQueueSize")) \
- PROBE(SerializeToPacketEnd, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, ui16, ui64, ui64), \
- NAMES("peerId", "channelId", "outputQueueSize", "offsetInPacket")) \
- PROBE(FillSendingBuffer, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, ui32, ui64, TDuration), \
- NAMES("peerId", "taskBytesGenerated", "numEventsInReadyChannelsBehind", "fillBlockedTotalMs")) \
- PROBE(PacketGenerated, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, ui64, ui64, ui64, ui64), \
- NAMES("peerId", "bytesUnwritten", "inflightBytes", "packetsGenerated", "packetSize")) \
- PROBE(PacketWrittenToSocket, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, ui64, bool, ui64, ui64, TDuration, int), \
- NAMES("peerId", "packetsWrittenToSocket", "triedWriting", "packetDataSize", "bytesUnwritten", "writeBlockedTotalMs", "fd")) \
- PROBE(GenerateTraffic, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, double, ui64, ui32, ui64), \
- NAMES("peerId", "generateTrafficMs", "dataBytesSent", "generatedPackets", "generatedBytes")) \
- PROBE(WriteToSocket, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, ui64, ui64, ui64, ui64, TDuration, int), \
- NAMES("peerId", "bytesWritten", "packetsWritten", "packetsWrittenToSocket", "bytesUnwritten", "writeBlockedTotalMs", "fd")) \
- PROBE(UpdateFromInputSession, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, double), \
- NAMES("peerId", "pingMs")) \
- PROBE(UnblockByDropConfirmed, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, double), \
- NAMES("peerId", "updateDeliveryMs")) \
- PROBE(DropConfirmed, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, ui64, ui64), \
- NAMES("peerId", "droppedBytes", "inflightBytes")) \
- PROBE(StartRam, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32), \
- NAMES("peerId")) \
- PROBE(FinishRam, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, double), \
- NAMES("peerId", "ramMs")) \
- PROBE(SkipGenerateTraffic, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, double), \
- NAMES("peerId", "elapsedSinceRamMs")) \
- PROBE(StartBatching, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, double), \
- NAMES("peerId", "batchPeriodMs")) \
- PROBE(FinishBatching, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, double), \
- NAMES("peerId", "finishBatchDeliveryMs")) \
- PROBE(BlockedWrite, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, double, ui64), \
- NAMES("peerId", "sendQueueSize", "writtenBytes")) \
- PROBE(ReadyWrite, GROUPS("InterconnectSessionTCP"), \
- TYPES(ui32, double, double), \
- NAMES("peerId", "readyWriteDeliveryMs", "blockMs")) \
- PROBE(EpollStartWaitIn, GROUPS("EpollThread"), \
- TYPES(), \
- NAMES()) \
- PROBE(EpollFinishWaitIn, GROUPS("EpollThread"), \
- TYPES(i32), \
- NAMES("eventsCount")) \
- PROBE(EpollWaitOut, GROUPS("EpollThread"), \
- TYPES(i32), \
- NAMES("eventsCount")) \
- PROBE(EpollSendReadyRead, GROUPS("EpollThread"), \
- TYPES(bool, bool, int), \
- NAMES("hangup", "event", "fd")) \
- PROBE(EpollSendReadyWrite, GROUPS("EpollThread"), \
- TYPES(bool, bool, int), \
- NAMES("hangup", "event", "fd")) \
- PROBE(HardPreemption, GROUPS("UnitedWorker"), \
- TYPES(ui32, ui32, ui32, ui32), \
- NAMES("cpu", "prevPoolId", "prevWorkerId", "nextWorkerId")) \
- PROBE(SetPreemptionTimer, GROUPS("UnitedWorker", "PreemptionTimer"), \
- TYPES(ui32, ui32, int, double, double), \
- NAMES("cpu", "workerId", "fd", "nowMs", "preemptMs")) \
- PROBE(ResetPreemptionTimer, GROUPS("UnitedWorker", "PreemptionTimer"), \
- TYPES(ui32, ui32, int, double, double), \
- NAMES("cpu", "workerId", "fd", "nowMs", "preemptMs")) \
- PROBE(SlowWorkerActionRace, GROUPS("UnitedWorker"), \
- TYPES(ui32, ui32, ui64), \
- NAMES("cpu", "poolId", "slowPoolsMask")) \
- PROBE(PoolStats, GROUPS("PoolCpuBalancer"), \
- TYPES(ui32, TString, ui64, ui8, ui8, double, double, double, ui64, ui64, ui64), \
- NAMES("poolId", "pool", "currentCpus", "loadClass", "priority", "scaleFactor", "cpuIdle", "cpuLoad", "importance", "addImportance", "subImportance")) \
- PROBE(MoveCpu, GROUPS("PoolCpuBalancer"), \
- TYPES(ui32, ui64, TString, TString, ui32), \
- NAMES("fromPoolId", "toPoolId", "fromPool", "toPool", "cpu")) \
- PROBE(ThreadCount, GROUPS("BasicThreadPool"), \
- TYPES(ui32, TString, ui32, ui32, ui32, ui32), \
- NAMES("poolId", "pool", "threacCount", "minThreadCount", "maxThreadCount", "defaultThreadCount")) \
- PROBE(HarmonizeCheckPool, GROUPS("Harmonizer"), \
- TYPES(ui32, TString, double, double, double, double, ui32, ui32, bool, bool, bool), \
- NAMES("poolId", "pool", "booked", "consumed", "lastSecondBooked", "lastSecondConsumed", "threadCount", "maxThreadCount", "isStarved", "isNeedy", "isHoggish")) \
- PROBE(WakingUpConsumption, GROUPS("Harmonizer"), \
- TYPES(double, double, double, double, double), \
- NAMES("avgWakingUpUs", "realAvgWakingUpUs", "avgAwakeningUs", "realAvgAwakeningUs", "total")) \
- PROBE(ChangeSpinThreshold, GROUPS("Harmonizer"), \
- TYPES(ui32, TString, ui64, double, ui64), \
- NAMES("poolId", "pool", "spinThreshold", "spinThresholdUs", "bucketIdx")) \
- PROBE(WaitingHistogram, GROUPS("Harmonizer"), \
- TYPES(ui32, TString, double, double, ui64), \
- NAMES("poolId", "pool", "fromUs", "toUs", "count")) \
- PROBE(HarmonizeOperation, GROUPS("Harmonizer"), \
- TYPES(ui32, TString, TString, ui32, ui32, ui32), \
- NAMES("poolId", "pool", "operation", "newCount", "minCount", "maxCount")) \
- PROBE(TryToHarmonize, GROUPS("Harmonizer"), \
- TYPES(ui32, TString), \
- NAMES("poolId", "pool")) \
- PROBE(SavedValues, GROUPS("Harmonizer"), \
- TYPES(ui32, TString, TString, double, double, double, double, double, double, double, double), \
- NAMES("poolId", "pool", "valueName", "[0]", "[1]", "[2]", "[3]", "[4]", "[5]", "[6]", "[7]")) \
- PROBE(RegisterValue, GROUPS("Harmonizer"), \
- TYPES(ui64, ui64, ui64, ui64, double, double, double), \
- NAMES("ts", "lastTs", "dTs", "8sTs", "us", "lastUs", "dUs")) \
- PROBE(TryToHarmonizeFailed, GROUPS("Harmonizer"), \
- TYPES(ui64, ui64, bool, bool), \
- NAMES("ts", "nextHarmonizeTs", "isDisabled", "withLock")) \
- PROBE(TryToHarmonizeSuccess, GROUPS("Harmonizer"), \
- TYPES(ui64, ui64, ui64), \
- NAMES("ts", "nextHarmonizeTs", "previousNextHarmonizeTs")) \
- PROBE(SpinCycles, GROUPS("Harmonizer"), \
- TYPES(ui32, TString, ui64, bool), \
- NAMES("poolId", "pool", "spinPauseCount", "IsInterrupted")) \
- PROBE(WaitingHistogramPerThread, GROUPS("Harmonizer"), \
- TYPES(ui32, TString, ui32, double, double, ui64), \
- NAMES("poolId", "pool", "threadIdx", "fromUs", "toUs", "count")) \
- PROBE(ChangeSpinThresholdPerThread, GROUPS("Harmonizer"), \
- TYPES(ui32, TString, ui32, ui64, double, ui64), \
- NAMES("poolId", "pool", "threadIdx", "spinThreshold", "spinThresholdUs", "bucketIdx")) \
- /**/
-
-LWTRACE_DECLARE_PROVIDER(ACTORLIB_PROVIDER)
-
-namespace NActors {
- struct TActorSystemSetup;
- TVector<NLWTrace::TDashboard> LWTraceDashboards(TActorSystemSetup* setup);
-}
diff --git a/library/cpp/actors/core/process_stats.cpp b/library/cpp/actors/core/process_stats.cpp
deleted file mode 100644
index f9028537c5..0000000000
--- a/library/cpp/actors/core/process_stats.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-#include "actorsystem.h"
-#include "actor_bootstrapped.h"
-#include "hfunc.h"
-#include "process_stats.h"
-
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-#include <library/cpp/monlib/metrics/metric_registry.h>
-
-#include <util/datetime/uptime.h>
-#include <util/system/defaults.h>
-#include <util/stream/file.h>
-#include <util/system/fs.h>
-#include <util/string/vector.h>
-#include <util/string/split.h>
-
-#ifndef _win_
-#include <sys/user.h>
-#endif
-
-namespace NActors {
-#ifdef _linux_
-
- namespace {
- template <typename TVal>
- static bool ExtractVal(const TString& str, const TString& name, TVal& res) {
- if (!str.StartsWith(name))
- return false;
- size_t pos = name.size();
- while (pos < str.size() && (str[pos] == ' ' || str[pos] == '\t')) {
- pos++;
- }
- res = atol(str.data() + pos);
- return true;
- }
-
- float TicksPerMillisec() {
-#ifdef _SC_CLK_TCK
- return sysconf(_SC_CLK_TCK) / 1000.0;
-#else
- return 1.f;
-#endif
- }
- }
-
- bool TProcStat::Fill(pid_t pid) {
- try {
- TString strPid(ToString(pid));
- TFileInput proc("/proc/" + strPid + "/status");
- TString str;
- while (proc.ReadLine(str)) {
- if (ExtractVal(str, "VmRSS:", Rss))
- continue;
- if (ExtractVal(str, "voluntary_ctxt_switches:", VolCtxSwtch))
- continue;
- if (ExtractVal(str, "nonvoluntary_ctxt_switches:", NonvolCtxSwtch))
- continue;
- }
- // Convert from kB to bytes
- Rss *= 1024;
-
- float tickPerMillisec = TicksPerMillisec();
-
- TFileInput procStat("/proc/" + strPid + "/stat");
- procStat.ReadLine(str);
- if (!str.empty()) {
- sscanf(str.data(),
- "%d %*s %c %d %d %d %d %d %u %lu %lu "
- "%lu %lu %lu %lu %ld %ld %ld %ld %ld "
- "%ld %llu %lu %ld %lu",
- &Pid, &State, &Ppid, &Pgrp, &Session, &TtyNr, &TPgid, &Flags, &MinFlt, &CMinFlt,
- &MajFlt, &CMajFlt, &Utime, &Stime, &CUtime, &CStime, &Priority, &Nice, &NumThreads,
- &ItRealValue, &StartTime, &Vsize, &RssPages, &RssLim);
- Utime /= tickPerMillisec;
- Stime /= tickPerMillisec;
- CUtime /= tickPerMillisec;
- CStime /= tickPerMillisec;
- SystemUptime = ::Uptime();
- Uptime = SystemUptime - TDuration::MilliSeconds(StartTime / TicksPerMillisec());
- }
-
- TFileInput statm("/proc/" + strPid + "/statm");
- statm.ReadLine(str);
- TVector<TString> fields;
- StringSplitter(str).Split(' ').SkipEmpty().Collect(&fields);
- if (fields.size() >= 7) {
- ui64 resident = FromString<ui64>(fields[1]);
- ui64 shared = FromString<ui64>(fields[2]);
- if (PageSize == 0) {
- PageSize = ObtainPageSize();
- }
- FileRss = shared * PageSize;
- AnonRss = (resident - shared) * PageSize;
- }
-
- TFileInput cgroup("/proc/" + strPid + "/cgroup");
- TString line;
- TString memoryCGroup;
- while (cgroup.ReadLine(line) > 0) {
- StringSplitter(line).Split(':').Collect(&fields);
- if (fields.size() > 2 && fields[1] == "memory") {
- memoryCGroup = fields[2];
- break;
- }
- }
-
- TString cgroupFileName = "/sys/fs/cgroup/memory" + memoryCGroup + "/memory.limit_in_bytes";
- if (!NFs::Exists(cgroupFileName)) {
- // fallback for mk8s
- cgroupFileName = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
- }
- TFileInput limit(cgroupFileName);
- if (limit.ReadLine(line) > 0) {
- CGroupMemLim = FromString<ui64>(line);
- if (CGroupMemLim > (1ULL << 40)) {
- CGroupMemLim = 0;
- }
- }
-
- } catch (...) {
- return false;
- }
- return true;
- }
-
- long TProcStat::ObtainPageSize() {
- long sz = sysconf(_SC_PAGESIZE);
- return sz;
- }
-
-#else
-
- bool TProcStat::Fill(pid_t pid) {
- Y_UNUSED(pid);
- return false;
- }
-
- long TProcStat::ObtainPageSize() {
- return 0;
- }
-
-#endif
-
-namespace {
- // Periodically collects process stats and exposes them as mon counters
- template <typename TDerived>
- class TProcStatCollectingActor: public TActorBootstrapped<TProcStatCollectingActor<TDerived>> {
- public:
- static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::EActivityType::ACTORLIB_STATS;
- }
-
- TProcStatCollectingActor(TDuration interval)
- : Interval(interval)
- {
- }
-
- void Bootstrap(const TActorContext& ctx) {
- TryUpdateCounters();
- ctx.Schedule(Interval, new TEvents::TEvWakeup());
- static_cast<TDerived*>(this)->Become(&TDerived::StateWork);
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- CFunc(TEvents::TSystem::Wakeup, Wakeup);
- }
- }
-
- private:
- void Wakeup(const TActorContext& ctx) {
- TryUpdateCounters();
- ctx.Schedule(Interval, new TEvents::TEvWakeup());
- }
-
- void TryUpdateCounters() {
- if (ProcStat.Fill(getpid())) {
- static_cast<TDerived*>(this)->UpdateCounters(ProcStat);
- }
- }
-
- private:
- const TDuration Interval;
- TProcStat ProcStat;
- };
-
- // Periodically collects process stats and exposes them as mon counters
- class TDynamicCounterCollector: public TProcStatCollectingActor<TDynamicCounterCollector> {
- using TBase = TProcStatCollectingActor<TDynamicCounterCollector>;
- public:
- TDynamicCounterCollector(
- ui32 intervalSeconds,
- NMonitoring::TDynamicCounterPtr counters)
- : TBase{TDuration::Seconds(intervalSeconds)}
- {
- ProcStatGroup = counters->GetSubgroup("counters", "utils");
-
- VmSize = ProcStatGroup->GetCounter("Process/VmSize", false);
- AnonRssSize = ProcStatGroup->GetCounter("Process/AnonRssSize", false);
- FileRssSize = ProcStatGroup->GetCounter("Process/FileRssSize", false);
- CGroupMemLimit = ProcStatGroup->GetCounter("Process/CGroupMemLimit", false);
- UserTime = ProcStatGroup->GetCounter("Process/UserTime", true);
- SysTime = ProcStatGroup->GetCounter("Process/SystemTime", true);
- MinorPageFaults = ProcStatGroup->GetCounter("Process/MinorPageFaults", true);
- MajorPageFaults = ProcStatGroup->GetCounter("Process/MajorPageFaults", true);
- UptimeSeconds = ProcStatGroup->GetCounter("Process/UptimeSeconds", false);
- NumThreads = ProcStatGroup->GetCounter("Process/NumThreads", false);
- SystemUptimeSeconds = ProcStatGroup->GetCounter("System/UptimeSeconds", false);
- }
-
- void UpdateCounters(const TProcStat& procStat) {
- *VmSize = procStat.Vsize;
- *AnonRssSize = procStat.AnonRss;
- *FileRssSize = procStat.FileRss;
- if (procStat.CGroupMemLim) {
- *CGroupMemLimit = procStat.CGroupMemLim;
- }
- *UserTime = procStat.Utime;
- *SysTime = procStat.Stime;
- *MinorPageFaults = procStat.MinFlt;
- *MajorPageFaults = procStat.MajFlt;
- *UptimeSeconds = procStat.Uptime.Seconds();
- *NumThreads = procStat.NumThreads;
- *SystemUptimeSeconds = procStat.Uptime.Seconds();
- }
-
- private:
- NMonitoring::TDynamicCounterPtr ProcStatGroup;
- NMonitoring::TDynamicCounters::TCounterPtr VmSize;
- NMonitoring::TDynamicCounters::TCounterPtr AnonRssSize;
- NMonitoring::TDynamicCounters::TCounterPtr FileRssSize;
- NMonitoring::TDynamicCounters::TCounterPtr CGroupMemLimit;
- NMonitoring::TDynamicCounters::TCounterPtr UserTime;
- NMonitoring::TDynamicCounters::TCounterPtr SysTime;
- NMonitoring::TDynamicCounters::TCounterPtr MinorPageFaults;
- NMonitoring::TDynamicCounters::TCounterPtr MajorPageFaults;
- NMonitoring::TDynamicCounters::TCounterPtr UptimeSeconds;
- NMonitoring::TDynamicCounters::TCounterPtr NumThreads;
- NMonitoring::TDynamicCounters::TCounterPtr SystemUptimeSeconds;
- };
-
- class TRegistryCollector: public TProcStatCollectingActor<TRegistryCollector> {
- using TBase = TProcStatCollectingActor<TRegistryCollector>;
- public:
- TRegistryCollector(TDuration interval, NMonitoring::TMetricRegistry& registry)
- : TBase{interval}
- {
- VmSize = registry.IntGauge({{"sensor", "process.VmSize"}});
- AnonRssSize = registry.IntGauge({{"sensor", "process.AnonRssSize"}});
- FileRssSize = registry.IntGauge({{"sensor", "process.FileRssSize"}});
- CGroupMemLimit = registry.IntGauge({{"sensor", "process.CGroupMemLimit"}});
- UptimeSeconds = registry.IntGauge({{"sensor", "process.UptimeSeconds"}});
- NumThreads = registry.IntGauge({{"sensor", "process.NumThreads"}});
- SystemUptimeSeconds = registry.IntGauge({{"sensor", "system.UptimeSeconds"}});
-
- UserTime = registry.Rate({{"sensor", "process.UserTime"}});
- SysTime = registry.Rate({{"sensor", "process.SystemTime"}});
- MinorPageFaults = registry.Rate({{"sensor", "process.MinorPageFaults"}});
- MajorPageFaults = registry.Rate({{"sensor", "process.MajorPageFaults"}});
- }
-
- void UpdateCounters(const TProcStat& procStat) {
- VmSize->Set(procStat.Vsize);
- AnonRssSize->Set(procStat.AnonRss);
- FileRssSize->Set(procStat.FileRss);
- CGroupMemLimit->Set(procStat.CGroupMemLim);
- UptimeSeconds->Set(procStat.Uptime.Seconds());
- NumThreads->Set(procStat.NumThreads);
- SystemUptimeSeconds->Set(procStat.SystemUptime.Seconds());
-
- // it is ok here to reset and add metric value, because mutation
- // is performed in siglethreaded context
-
- UserTime->Reset();
- UserTime->Add(procStat.Utime);
-
- SysTime->Reset();
- SysTime->Add(procStat.Stime);
-
- MinorPageFaults->Reset();
- MinorPageFaults->Add(procStat.MinFlt);
-
- MajorPageFaults->Reset();
- MajorPageFaults->Add(procStat.MajFlt);
- }
-
- private:
- NMonitoring::TIntGauge* VmSize;
- NMonitoring::TIntGauge* AnonRssSize;
- NMonitoring::TIntGauge* FileRssSize;
- NMonitoring::TIntGauge* CGroupMemLimit;
- NMonitoring::TRate* UserTime;
- NMonitoring::TRate* SysTime;
- NMonitoring::TRate* MinorPageFaults;
- NMonitoring::TRate* MajorPageFaults;
- NMonitoring::TIntGauge* UptimeSeconds;
- NMonitoring::TIntGauge* NumThreads;
- NMonitoring::TIntGauge* SystemUptimeSeconds;
- };
-
- class TRegistryCollectorShared: public TProcStatCollectingActor<TRegistryCollectorShared> {
- using TBase = TProcStatCollectingActor<TRegistryCollectorShared>;
- public:
- TRegistryCollectorShared(TDuration interval, std::weak_ptr<NMonitoring::TMetricRegistry> registry)
- : TBase{interval}
- , Registry(std::move(registry))
- {
- }
-
- void UpdateCounters(const TProcStat& procStat) {
- std::shared_ptr<NMonitoring::TMetricRegistry> registry = Registry.lock();
- if (registry) {
- registry->IntGauge({{"sensor", "process.VmSize"}})->Set(procStat.Vsize);
- registry->IntGauge({{"sensor", "process.AnonRssSize"}})->Set(procStat.AnonRss);
- registry->IntGauge({{"sensor", "process.FileRssSize"}})->Set(procStat.FileRss);
- registry->IntGauge({{"sensor", "process.CGroupMemLimit"}})->Set(procStat.CGroupMemLim);
- registry->IntGauge({{"sensor", "process.UptimeSeconds"}})->Set(procStat.Uptime.Seconds());
- registry->IntGauge({{"sensor", "process.NumThreads"}})->Set(procStat.NumThreads);
- registry->IntGauge({{"sensor", "system.UptimeSeconds"}})->Set(procStat.SystemUptime.Seconds());
-
- // it is ok here to reset and add metric value, because mutation
- // is performed in siglethreaded context
-
- NMonitoring::TRate* userTime = registry->Rate({{"sensor", "process.UserTime"}});
- NMonitoring::TRate* sysTime = registry->Rate({{"sensor", "process.SystemTime"}});
- NMonitoring::TRate* minorPageFaults = registry->Rate({{"sensor", "process.MinorPageFaults"}});
- NMonitoring::TRate* majorPageFaults = registry->Rate({{"sensor", "process.MajorPageFaults"}});
-
- userTime->Reset();
- userTime->Add(procStat.Utime);
-
- sysTime->Reset();
- sysTime->Add(procStat.Stime);
-
- minorPageFaults->Reset();
- minorPageFaults->Add(procStat.MinFlt);
-
- majorPageFaults->Reset();
- majorPageFaults->Add(procStat.MajFlt);
- }
- }
-
- private:
- std::weak_ptr<NMonitoring::TMetricRegistry> Registry;
- };
-} // namespace
-
- IActor* CreateProcStatCollector(ui32 intervalSec, NMonitoring::TDynamicCounterPtr counters) {
- return new TDynamicCounterCollector(intervalSec, counters);
- }
-
- IActor* CreateProcStatCollector(TDuration interval, NMonitoring::TMetricRegistry& registry) {
- return new TRegistryCollector(interval, registry);
- }
-
- IActor* CreateProcStatCollector(TDuration interval, std::weak_ptr<NMonitoring::TMetricRegistry> registry) {
- return new TRegistryCollectorShared(interval, std::move(registry));
- }
-}
diff --git a/library/cpp/actors/core/process_stats.h b/library/cpp/actors/core/process_stats.h
deleted file mode 100644
index 5681f0eb1a..0000000000
--- a/library/cpp/actors/core/process_stats.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include "actor.h"
-
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-namespace NMonitoring {
- class TMetricRegistry;
-}
-
-namespace NActors {
- struct TProcStat {
- ui64 Rss;
- ui64 VolCtxSwtch;
- ui64 NonvolCtxSwtch;
-
- int Pid;
- char State;
- int Ppid;
- int Pgrp;
- int Session;
- int TtyNr;
- int TPgid;
- unsigned Flags;
- unsigned long MinFlt;
- unsigned long CMinFlt;
- unsigned long MajFlt;
- unsigned long CMajFlt;
- unsigned long Utime;
- unsigned long Stime;
- long CUtime;
- long CStime;
- long Priority;
- long Nice;
- long NumThreads;
- long ItRealValue;
- // StartTime is measured from system boot
- unsigned long long StartTime;
- unsigned long Vsize;
- long RssPages;
- unsigned long RssLim;
- ui64 FileRss;
- ui64 AnonRss;
- ui64 CGroupMemLim = 0;
-
- TDuration Uptime;
- TDuration SystemUptime;
- // ...
-
- TProcStat() {
- Zero(*this);
- Y_UNUSED(PageSize);
- }
-
- bool Fill(pid_t pid);
-
- private:
- long PageSize = 0;
-
- long ObtainPageSize();
- };
-
- IActor* CreateProcStatCollector(ui32 intervalSec, NMonitoring::TDynamicCounterPtr counters);
- IActor* CreateProcStatCollector(TDuration interval, NMonitoring::TMetricRegistry& registry);
- IActor* CreateProcStatCollector(TDuration interval, std::weak_ptr<NMonitoring::TMetricRegistry> registry);
-}
diff --git a/library/cpp/actors/core/scheduler_actor.cpp b/library/cpp/actors/core/scheduler_actor.cpp
deleted file mode 100644
index 73fd6bd183..0000000000
--- a/library/cpp/actors/core/scheduler_actor.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-#include "actor_bootstrapped.h"
-#include "hfunc.h"
-#include "probes.h"
-#include "scheduler_actor.h"
-#include "scheduler_queue.h"
-
-#include <library/cpp/actors/interconnect/poller_actor.h>
-#include <util/system/hp_timer.h>
-
-#ifdef __linux__
-#include <sys/timerfd.h>
-#include <errno.h>
-
-LWTRACE_USING(ACTORLIB_PROVIDER);
-
-namespace NActors {
- class TTimerDescriptor: public TSharedDescriptor {
- const int Descriptor;
-
- public:
- TTimerDescriptor()
- : Descriptor(timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK))
- {
- Y_ABORT_UNLESS(Descriptor != -1, "timerfd_create() failed with %s", strerror(errno));
- }
-
- ~TTimerDescriptor() override {
- close(Descriptor);
- }
-
- int GetDescriptor() override {
- return Descriptor;
- }
- };
-
- class TSchedulerActor: public TActor<TSchedulerActor> {
- const TSchedulerConfig Cfg;
- TIntrusivePtr<TSharedDescriptor> TimerDescriptor;
-
- TVector<NSchedulerQueue::TReader*> Readers;
-
- TActorId PollerActor;
- TPollerToken::TPtr PollerToken;
-
- ui64 RealTime;
- ui64 MonotonicTime;
-
- ui64 ActiveTick;
- typedef TMap<ui64, TAutoPtr<NSchedulerQueue::TQueueType>> TMomentMap; // intrasecond queues
- typedef THashMap<ui64, TAutoPtr<TMomentMap>> TScheduleMap; // over-second schedule
-
- TScheduleMap ScheduleMap;
-
- THolder<NThreading::TLegacyFuture<void, false>> MainCycle;
-
- static const ui64 IntrasecondThreshold = 1048576; // ~second
- TAutoPtr<TMomentMap> ActiveSec;
- volatile ui64* CurrentTimestamp = nullptr;
- volatile ui64* CurrentMonotonic = nullptr;
- TDeque<TAutoPtr<IEventHandle>> EventsToBeSent;
-
- public:
- static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::EActivityType::ACTOR_SYSTEM_SCHEDULER_ACTOR;
- }
-
- TSchedulerActor(const TSchedulerConfig& cfg)
- : TActor(&TSchedulerActor::StateFunc)
- , Cfg(cfg)
- , TimerDescriptor(new TTimerDescriptor())
- , PollerActor(MakePollerActorId())
- {
- Y_ASSERT(Cfg.ResolutionMicroseconds != 0);
- Y_ASSERT(Cfg.ProgressThreshold != 0);
- Become(&TSchedulerActor::StateFunc);
- }
-
- void Handle(TEvSchedulerInitialize::TPtr& ev, const TActorContext& ctx) {
- const TEvSchedulerInitialize& evInitialize = *ev->Get();
- Y_ASSERT(evInitialize.ScheduleReaders.size() != 0);
- Readers.resize(evInitialize.ScheduleReaders.size());
- Copy(evInitialize.ScheduleReaders.begin(), evInitialize.ScheduleReaders.end(), Readers.begin());
-
- Y_ASSERT(evInitialize.CurrentTimestamp != nullptr);
- CurrentTimestamp = evInitialize.CurrentTimestamp;
-
- Y_ASSERT(evInitialize.CurrentMonotonic != nullptr);
- CurrentMonotonic = evInitialize.CurrentMonotonic;
-
- struct itimerspec new_time;
- memset(&new_time, 0, sizeof(new_time));
- new_time.it_value.tv_nsec = Cfg.ResolutionMicroseconds * 1000;
- new_time.it_interval.tv_nsec = Cfg.ResolutionMicroseconds * 1000;
- int ret = timerfd_settime(TimerDescriptor->GetDescriptor(), 0, &new_time, NULL);
- Y_ABORT_UNLESS(ret != -1, "timerfd_settime() failed with %s", strerror(errno));
- const bool success = ctx.Send(PollerActor, new TEvPollerRegister(TimerDescriptor, SelfId(), {}));
- Y_ABORT_UNLESS(success);
-
- RealTime = RelaxedLoad(CurrentTimestamp);
- MonotonicTime = RelaxedLoad(CurrentMonotonic);
-
- ActiveTick = AlignUp<ui64>(MonotonicTime, IntrasecondThreshold);
- }
-
- void Handle(TEvPollerRegisterResult::TPtr ev, const TActorContext& ctx) {
- PollerToken = ev->Get()->PollerToken;
- HandleSchedule(ctx);
- }
-
- void UpdateTime() {
- RealTime = TInstant::Now().MicroSeconds();
- MonotonicTime = Max(MonotonicTime, GetMonotonicMicroSeconds());
- AtomicStore(CurrentTimestamp, RealTime);
- AtomicStore(CurrentMonotonic, MonotonicTime);
- }
-
- void TryUpdateTime(NHPTimer::STime* lastTimeUpdate) {
- NHPTimer::STime hpnow;
- GetTimeFast(&hpnow);
- const ui64 elapsedCycles = hpnow > *lastTimeUpdate ? hpnow - *lastTimeUpdate : 0;
- if (elapsedCycles > Cfg.ResolutionMicroseconds * (NHPTimer::GetCyclesPerSecond() / IntrasecondThreshold)) {
- UpdateTime();
- GetTimeFast(lastTimeUpdate);
- }
- }
-
- 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_ABORT_UNLESS(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_DEBUG_ABORT_UNLESS(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);
- }
- }
- ActiveSec->erase(it);
- } else {
- break;
- }
- }
-
- if (ActiveTick <= MonotonicTime) {
- Y_DEBUG_ABORT_UNLESS(!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().Release());
- 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)
- )
- };
-
- IActor* CreateSchedulerActor(const TSchedulerConfig& cfg) {
- if (cfg.UseSchedulerActor) {
- return new TSchedulerActor(cfg);
- } else {
- return nullptr;
- }
- }
-
-}
-
-#else // linux
-
-namespace NActors {
- IActor* CreateSchedulerActor(const TSchedulerConfig& cfg) {
- Y_UNUSED(cfg);
- return nullptr;
- }
-
-}
-
-#endif // linux
diff --git a/library/cpp/actors/core/scheduler_actor.h b/library/cpp/actors/core/scheduler_actor.h
deleted file mode 100644
index c2c561b43d..0000000000
--- a/library/cpp/actors/core/scheduler_actor.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include "actor.h"
-#include "event_local.h"
-#include "events.h"
-#include "scheduler_basic.h"
-
-namespace NActors {
- struct TEvSchedulerInitialize : TEventLocal<TEvSchedulerInitialize, TEvents::TSystem::Bootstrap> {
- TVector<NSchedulerQueue::TReader*> ScheduleReaders;
- volatile ui64* CurrentTimestamp;
- volatile ui64* CurrentMonotonic;
-
- TEvSchedulerInitialize(const TVector<NSchedulerQueue::TReader*>& scheduleReaders, volatile ui64* currentTimestamp, volatile ui64* currentMonotonic)
- : ScheduleReaders(scheduleReaders)
- , CurrentTimestamp(currentTimestamp)
- , CurrentMonotonic(currentMonotonic)
- {
- }
- };
-
- IActor* CreateSchedulerActor(const TSchedulerConfig& cfg);
-
- inline TActorId MakeSchedulerActorId() {
- char x[12] = {'s', 'c', 'h', 'e', 'd', 'u', 'l', 'e', 'r', 's', 'e', 'r'};
- return TActorId(0, TStringBuf(x, 12));
- }
-
-}
diff --git a/library/cpp/actors/core/scheduler_actor_ut.cpp b/library/cpp/actors/core/scheduler_actor_ut.cpp
deleted file mode 100644
index 09b7369d36..0000000000
--- a/library/cpp/actors/core/scheduler_actor_ut.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-#include "actor_coroutine.h"
-#include "actorsystem.h"
-#include "executor_pool_basic.h"
-#include "scheduler_actor.h"
-#include "scheduler_basic.h"
-#include "events.h"
-#include "event_local.h"
-#include "hfunc.h"
-#include <library/cpp/actors/interconnect/poller_actor.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/system/sanitizers.h>
-
-using namespace NActors;
-
-Y_UNIT_TEST_SUITE(SchedulerActor) {
- class TTestActor: public TActorBootstrapped<TTestActor> {
- TManualEvent& DoneEvent;
- TAtomic& EventsProcessed;
- TInstant LastWakeup;
- const TAtomicBase EventsTotalCount;
- const TDuration ScheduleDelta;
-
- public:
- TTestActor(TManualEvent& doneEvent, TAtomic& eventsProcessed, TAtomicBase eventsTotalCount, ui32 scheduleDeltaMs)
- : DoneEvent(doneEvent)
- , EventsProcessed(eventsProcessed)
- , EventsTotalCount(eventsTotalCount)
- , ScheduleDelta(TDuration::MilliSeconds(scheduleDeltaMs))
- {
- }
-
- void Bootstrap(const TActorContext& ctx) {
- LastWakeup = ctx.Now();
- Become(&TThis::StateFunc);
- ctx.Schedule(ScheduleDelta, new TEvents::TEvWakeup());
- }
-
- void Handle(TEvents::TEvWakeup::TPtr& /*ev*/, const TActorContext& ctx) {
- const TInstant now = ctx.Now();
- UNIT_ASSERT(now - LastWakeup >= ScheduleDelta);
- LastWakeup = now;
-
- if (AtomicIncrement(EventsProcessed) == EventsTotalCount) {
- DoneEvent.Signal();
- } else {
- ctx.Schedule(ScheduleDelta, new TEvents::TEvWakeup());
- }
- }
-
- STRICT_STFUNC(StateFunc, {HFunc(TEvents::TEvWakeup, Handle)})
- };
-
- void Test(TAtomicBase eventsTotalCount, ui32 scheduleDeltaMs) {
- THolder<TActorSystemSetup> setup = MakeHolder<TActorSystemSetup>();
- 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");
- }
- // create poller actor (whether platform supports it)
- TActorId pollerActorId;
- if (IActor* poller = CreatePollerActor()) {
- pollerActorId = MakePollerActorId();
- setup->LocalServices.emplace_back(pollerActorId, TActorSetupCmd(poller, TMailboxType::ReadAsFilled, 0));
- }
- TActorId schedulerActorId;
- if (IActor* schedulerActor = CreateSchedulerActor(TSchedulerConfig())) {
- schedulerActorId = MakeSchedulerActorId();
- setup->LocalServices.emplace_back(schedulerActorId, TActorSetupCmd(schedulerActor, TMailboxType::ReadAsFilled, 0));
- }
- setup->Scheduler = CreateSchedulerThread(TSchedulerConfig());
-
- TActorSystem actorSystem(setup);
-
- actorSystem.Start();
-
- TManualEvent doneEvent;
- TAtomic eventsProcessed = 0;
- actorSystem.Register(new TTestActor(doneEvent, eventsProcessed, eventsTotalCount, scheduleDeltaMs));
- doneEvent.WaitI();
-
- UNIT_ASSERT(AtomicGet(eventsProcessed) == eventsTotalCount);
-
- actorSystem.Stop();
- }
-
- Y_UNIT_TEST(LongEvents) {
- Test(10, 500);
- }
-
- Y_UNIT_TEST(MediumEvents) {
- Test(100, 50);
- }
-
- Y_UNIT_TEST(QuickEvents) {
- Test(1000, 5);
- }
-}
diff --git a/library/cpp/actors/core/scheduler_basic.cpp b/library/cpp/actors/core/scheduler_basic.cpp
deleted file mode 100644
index 5d66224f05..0000000000
--- a/library/cpp/actors/core/scheduler_basic.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-#include "scheduler_basic.h"
-#include "scheduler_queue.h"
-#include "actor.h"
-
-#include <library/cpp/actors/util/datetime.h>
-#include <library/cpp/actors/util/thread.h>
-
-#ifdef BALLOC
-#include <library/cpp/balloc/optional/operators.h>
-#endif
-
-namespace NActors {
-
- struct TBasicSchedulerThread::TMonCounters {
- NMonitoring::TDynamicCounters::TCounterPtr TimeDelayMs;
- NMonitoring::TDynamicCounters::TCounterPtr QueueSize;
- NMonitoring::TDynamicCounters::TCounterPtr EventsSent;
- NMonitoring::TDynamicCounters::TCounterPtr EventsDropped;
- NMonitoring::TDynamicCounters::TCounterPtr EventsAdded;
- NMonitoring::TDynamicCounters::TCounterPtr Iterations;
- NMonitoring::TDynamicCounters::TCounterPtr Sleeps;
- NMonitoring::TDynamicCounters::TCounterPtr ElapsedMicrosec;
-
- TMonCounters(const NMonitoring::TDynamicCounterPtr& counters)
- : TimeDelayMs(counters->GetCounter("Scheduler/TimeDelayMs", false))
- , QueueSize(counters->GetCounter("Scheduler/QueueSize", false))
- , EventsSent(counters->GetCounter("Scheduler/EventsSent", true))
- , EventsDropped(counters->GetCounter("Scheduler/EventsDropped", true))
- , EventsAdded(counters->GetCounter("Scheduler/EventsAdded", true))
- , Iterations(counters->GetCounter("Scheduler/Iterations", true))
- , Sleeps(counters->GetCounter("Scheduler/Sleeps", true))
- , ElapsedMicrosec(counters->GetCounter("Scheduler/ElapsedMicrosec", true))
- { }
- };
-
- TBasicSchedulerThread::TBasicSchedulerThread(const TSchedulerConfig& config)
- : Config(config)
- , MonCounters(Config.MonCounters ? new TMonCounters(Config.MonCounters) : nullptr)
- , ActorSystem(nullptr)
- , CurrentTimestamp(nullptr)
- , CurrentMonotonic(nullptr)
- , TotalReaders(0)
- , StopFlag(false)
- , ScheduleMap(3600)
- {
- Y_ABORT_UNLESS(!Config.UseSchedulerActor, "Cannot create scheduler thread because Config.UseSchedulerActor# true");
- }
-
- TBasicSchedulerThread::~TBasicSchedulerThread() {
- Y_ABORT_UNLESS(!MainCycle);
- }
-
- void TBasicSchedulerThread::CycleFunc() {
-#ifdef BALLOC
- ThreadDisableBalloc();
-#endif
- ::SetCurrentThreadName("Scheduler");
-
- ui64 currentMonotonic = RelaxedLoad(CurrentMonotonic);
- ui64 throttledMonotonic = currentMonotonic;
-
- ui64 activeTick = AlignUp<ui64>(throttledMonotonic, IntrasecondThreshold);
- TAutoPtr<TMomentMap> activeSec;
-
- NHPTimer::STime hpprev = GetCycleCountFast();
- ui64 nextTimestamp = TInstant::Now().MicroSeconds();
- ui64 nextMonotonic = Max(currentMonotonic, GetMonotonicMicroSeconds());
-
- while (!AtomicLoad(&StopFlag)) {
- {
- const ui64 delta = nextMonotonic - throttledMonotonic;
- const ui64 elapsedDelta = nextMonotonic - currentMonotonic;
- const ui64 threshold = Max(Min(Config.ProgressThreshold, 2 * elapsedDelta), ui64(1));
-
- throttledMonotonic = (delta > threshold) ? throttledMonotonic + threshold : nextMonotonic;
-
- if (MonCounters) {
- *MonCounters->TimeDelayMs = (nextMonotonic - throttledMonotonic) / 1000;
- }
- }
- AtomicStore(CurrentTimestamp, nextTimestamp);
- AtomicStore(CurrentMonotonic, nextMonotonic);
- currentMonotonic = nextMonotonic;
-
- if (MonCounters) {
- ++*MonCounters->Iterations;
- }
-
- bool somethingDone = false;
-
- // first step - send everything triggered on schedule
- ui64 eventsSent = 0;
- ui64 eventsDropped = 0;
- for (;;) {
- while (!!activeSec && !activeSec->empty()) {
- TMomentMap::iterator it = activeSec->begin();
- if (it->first <= throttledMonotonic) {
- if (NSchedulerQueue::TQueueType* q = it->second.Get()) {
- while (NSchedulerQueue::TEntry* x = q->Reader.Pop()) {
- somethingDone = true;
- Y_DEBUG_ABORT_UNLESS(x->InstantMicroseconds <= activeTick);
- IEventHandle* ev = x->Ev;
- ISchedulerCookie* cookie = x->Cookie;
- // TODO: lazy send with backoff queue to not hang over contended mailboxes
- if (cookie) {
- if (cookie->Detach()) {
- ActorSystem->Send(ev);
- ++eventsSent;
- } else {
- delete ev;
- ++eventsDropped;
- }
- } else {
- ActorSystem->Send(ev);
- ++eventsSent;
- }
- }
- }
- activeSec->erase(it);
- } else
- break;
- }
-
- if (activeTick <= throttledMonotonic) {
- Y_DEBUG_ABORT_UNLESS(!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;
- }
-
- // second step - collect everything from queues
-
- ui64 eventsAdded = 0;
- for (ui32 i = 0; i != TotalReaders; ++i) {
- while (NSchedulerQueue::TEntry* x = Readers[i]->Pop()) {
- somethingDone = true;
- const ui64 instant = AlignUp<ui64>(x->InstantMicroseconds, Config.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);
- }
-
- ++eventsAdded;
- }
- }
-
- NHPTimer::STime hpnow = GetCycleCountFast();
-
- if (MonCounters) {
- *MonCounters->QueueSize -= eventsSent + eventsDropped;
- *MonCounters->QueueSize += eventsAdded;
- *MonCounters->EventsSent += eventsSent;
- *MonCounters->EventsDropped += eventsDropped;
- *MonCounters->EventsAdded += eventsAdded;
- *MonCounters->ElapsedMicrosec += NHPTimer::GetSeconds(hpnow - hpprev) * 1000000;
- }
-
- hpprev = hpnow;
- nextTimestamp = TInstant::Now().MicroSeconds();
- nextMonotonic = Max(currentMonotonic, GetMonotonicMicroSeconds());
-
- // ok complete, if nothing left - sleep
- if (!somethingDone) {
- const ui64 nextInstant = AlignDown<ui64>(throttledMonotonic + Config.ResolutionMicroseconds, Config.ResolutionMicroseconds);
- if (nextMonotonic >= nextInstant) // already in next time-slice
- continue;
-
- const ui64 delta = nextInstant - nextMonotonic;
- if (delta < Config.SpinThreshold) // not so much time left, just spin
- continue;
-
- if (MonCounters) {
- ++*MonCounters->Sleeps;
- }
-
- NanoSleep(delta * 1000); // ok, looks like we should sleep a bit.
-
- // Don't count sleep in elapsed microseconds
- hpprev = GetCycleCountFast();
- nextTimestamp = TInstant::Now().MicroSeconds();
- nextMonotonic = Max(currentMonotonic, GetMonotonicMicroSeconds());
- }
- }
- // ok, die!
- }
-
- void TBasicSchedulerThread::Prepare(TActorSystem* actorSystem, volatile ui64* currentTimestamp, volatile ui64* currentMonotonic) {
- ActorSystem = actorSystem;
- CurrentTimestamp = currentTimestamp;
- CurrentMonotonic = currentMonotonic;
- *CurrentTimestamp = TInstant::Now().MicroSeconds();
- *CurrentMonotonic = GetMonotonicMicroSeconds();
- }
-
- void TBasicSchedulerThread::PrepareSchedules(NSchedulerQueue::TReader** readers, ui32 scheduleReadersCount) {
- Y_ABORT_UNLESS(scheduleReadersCount > 0);
- TotalReaders = scheduleReadersCount;
- Readers.Reset(new NSchedulerQueue::TReader*[scheduleReadersCount]);
- Copy(readers, readers + scheduleReadersCount, Readers.Get());
- }
-
- void TBasicSchedulerThread::PrepareStart() {
- // Called after actor system is initialized, but before executor threads
- // are started, giving us a chance to update current timestamp with a
- // more recent value, taking initialization time into account. This is
- // safe to do, since scheduler thread is not started yet, so no other
- // threads are updating time concurrently.
- AtomicStore(CurrentTimestamp, TInstant::Now().MicroSeconds());
- AtomicStore(CurrentMonotonic, Max(RelaxedLoad(CurrentMonotonic), GetMonotonicMicroSeconds()));
- }
-
- void TBasicSchedulerThread::Start() {
- MainCycle.Reset(new NThreading::TLegacyFuture<void, false>(std::bind(&TBasicSchedulerThread::CycleFunc, this)));
- }
-
- void TBasicSchedulerThread::PrepareStop() {
- AtomicStore(&StopFlag, true);
- }
-
- void TBasicSchedulerThread::Stop() {
- MainCycle->Get();
- MainCycle.Destroy();
- }
-
-}
-
-#ifdef __linux__
-
-namespace NActors {
- ISchedulerThread* CreateSchedulerThread(const TSchedulerConfig& config) {
- if (config.UseSchedulerActor) {
- return new TMockSchedulerThread();
- } else {
- return new TBasicSchedulerThread(config);
- }
- }
-
-}
-
-#else // __linux__
-
-namespace NActors {
- ISchedulerThread* CreateSchedulerThread(const TSchedulerConfig& config) {
- return new TBasicSchedulerThread(config);
- }
-}
-
-#endif // __linux__
diff --git a/library/cpp/actors/core/scheduler_basic.h b/library/cpp/actors/core/scheduler_basic.h
deleted file mode 100644
index 2ccde39235..0000000000
--- a/library/cpp/actors/core/scheduler_basic.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#pragma once
-
-#include "actorsystem.h"
-#include "monotonic.h"
-#include "scheduler_queue.h"
-#include <library/cpp/actors/util/queue_chunk.h>
-#include <library/cpp/threading/future/legacy_future.h>
-#include <util/generic/hash.h>
-#include <util/generic/map.h>
-
-namespace NActors {
-
- class TBasicSchedulerThread: public ISchedulerThread {
- // TODO: replace with NUMA-local threads and per-thread schedules
- const TSchedulerConfig Config;
-
- struct TMonCounters;
- const THolder<TMonCounters> MonCounters;
-
- TActorSystem* ActorSystem;
- volatile ui64* CurrentTimestamp;
- volatile ui64* CurrentMonotonic;
-
- ui32 TotalReaders;
- TArrayHolder<NSchedulerQueue::TReader*> Readers;
-
- volatile bool StopFlag;
-
- typedef TMap<ui64, TAutoPtr<NSchedulerQueue::TQueueType>> TMomentMap; // intrasecond queues
- typedef THashMap<ui64, TAutoPtr<TMomentMap>> TScheduleMap; // over-second schedule
-
- TScheduleMap ScheduleMap;
-
- THolder<NThreading::TLegacyFuture<void, false>> MainCycle;
-
- static const ui64 IntrasecondThreshold = 1048576; // ~second
-
- void CycleFunc();
-
- public:
- TBasicSchedulerThread(const TSchedulerConfig& config = TSchedulerConfig());
- ~TBasicSchedulerThread();
-
- void Prepare(TActorSystem* actorSystem, volatile ui64* currentTimestamp, volatile ui64* currentMonotonic) override;
- void PrepareSchedules(NSchedulerQueue::TReader** readers, ui32 scheduleReadersCount) override;
-
- void PrepareStart() override;
- void Start() override;
- void PrepareStop() override;
- void Stop() override;
- };
-
- class TMockSchedulerThread: public ISchedulerThread {
- public:
- virtual ~TMockSchedulerThread() override {
- }
-
- void Prepare(TActorSystem* actorSystem, volatile ui64* currentTimestamp, volatile ui64* currentMonotonic) override {
- Y_UNUSED(actorSystem);
- *currentTimestamp = TInstant::Now().MicroSeconds();
- *currentMonotonic = GetMonotonicMicroSeconds();
- }
-
- void PrepareSchedules(NSchedulerQueue::TReader** readers, ui32 scheduleReadersCount) override {
- Y_UNUSED(readers);
- Y_UNUSED(scheduleReadersCount);
- }
-
- void Start() override {
- }
-
- void PrepareStop() override {
- }
-
- void Stop() override {
- }
- };
-
- ISchedulerThread* CreateSchedulerThread(const TSchedulerConfig& cfg);
-
-}
diff --git a/library/cpp/actors/core/scheduler_cookie.cpp b/library/cpp/actors/core/scheduler_cookie.cpp
deleted file mode 100644
index b975a80c07..0000000000
--- a/library/cpp/actors/core/scheduler_cookie.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-#include "scheduler_cookie.h"
-
-namespace NActors {
- class TSchedulerCookie2Way: public ISchedulerCookie {
- TAtomic Value;
-
- public:
- TSchedulerCookie2Way()
- : Value(2)
- {
- }
-
- bool IsArmed() noexcept override {
- return (AtomicGet(Value) == 2);
- }
-
- bool Detach() noexcept override {
- const ui64 x = AtomicDecrement(Value);
- if (x == 1)
- return true;
-
- if (x == 0) {
- delete this;
- return false;
- }
-
- Y_ABORT();
- }
-
- bool DetachEvent() noexcept override {
- Y_ABORT();
- }
- };
-
- ISchedulerCookie* ISchedulerCookie::Make2Way() {
- return new TSchedulerCookie2Way();
- }
-
- class TSchedulerCookie3Way: public ISchedulerCookie {
- TAtomic Value;
-
- public:
- TSchedulerCookie3Way()
- : Value(3)
- {
- }
-
- bool IsArmed() noexcept override {
- return (AtomicGet(Value) == 3);
- }
-
- bool Detach() noexcept override {
- const ui64 x = AtomicDecrement(Value);
- if (x == 2)
- return true;
- if (x == 1)
- return false;
- if (x == 0) {
- delete this;
- return false;
- }
-
- Y_ABORT();
- }
-
- bool DetachEvent() noexcept override {
- const ui64 x = AtomicDecrement(Value);
- if (x == 2)
- return false;
- if (x == 1)
- return true;
- if (x == 0) {
- delete this;
- return false;
- }
-
- Y_ABORT();
- }
- };
-
- ISchedulerCookie* ISchedulerCookie::Make3Way() {
- return new TSchedulerCookie3Way();
- }
-}
diff --git a/library/cpp/actors/core/scheduler_cookie.h b/library/cpp/actors/core/scheduler_cookie.h
deleted file mode 100644
index 2c20ca67f3..0000000000
--- a/library/cpp/actors/core/scheduler_cookie.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include <util/generic/noncopyable.h>
-
-namespace NActors {
- class ISchedulerCookie : TNonCopyable {
- protected:
- virtual ~ISchedulerCookie() {
- }
-
- public:
- virtual bool Detach() noexcept = 0;
- virtual bool DetachEvent() noexcept = 0;
- virtual bool IsArmed() noexcept = 0;
-
- static ISchedulerCookie* Make2Way();
- static ISchedulerCookie* Make3Way();
- };
-
- class TSchedulerCookieHolder : TNonCopyable {
- ISchedulerCookie* Cookie;
-
- public:
- TSchedulerCookieHolder()
- : Cookie(nullptr)
- {
- }
-
- TSchedulerCookieHolder(ISchedulerCookie* x)
- : Cookie(x)
- {
- }
-
- ~TSchedulerCookieHolder() {
- Detach();
- }
-
- bool operator==(const TSchedulerCookieHolder& x) const noexcept {
- return (Cookie == x.Cookie);
- }
-
- ISchedulerCookie* Get() const {
- return Cookie;
- }
-
- ISchedulerCookie* Release() {
- ISchedulerCookie* result = Cookie;
- Cookie = nullptr;
- return result;
- }
-
- void Reset(ISchedulerCookie* cookie) {
- Detach();
- Cookie = cookie;
- }
-
- bool Detach() noexcept {
- if (Cookie) {
- const bool res = Cookie->Detach();
- Cookie = nullptr;
- return res;
- } else {
- return false;
- }
- }
-
- bool DetachEvent() noexcept {
- if (Cookie) {
- const bool res = Cookie->DetachEvent();
- Cookie = nullptr;
- return res;
- } else {
- return false;
- }
- }
- };
-}
diff --git a/library/cpp/actors/core/scheduler_queue.h b/library/cpp/actors/core/scheduler_queue.h
deleted file mode 100644
index 8d827e1ce4..0000000000
--- a/library/cpp/actors/core/scheduler_queue.h
+++ /dev/null
@@ -1,123 +0,0 @@
-#pragma once
-
-#include "scheduler_cookie.h"
-
-#include <library/cpp/actors/util/queue_chunk.h>
-#include <library/cpp/actors/core/event.h>
-
-namespace NActors {
- class IEventHandle;
- class ISchedulerCookie;
-
- namespace NSchedulerQueue {
- struct TEntry {
- ui64 InstantMicroseconds;
- IEventHandle* Ev;
- ISchedulerCookie* Cookie;
- };
-
- struct TChunk : TQueueChunkDerived<TEntry, 512, TChunk> {};
-
- class TReader;
- class TWriter;
- class TWriterWithPadding;
-
- class TReader : ::TNonCopyable {
- TChunk* ReadFrom;
- ui32 ReadPosition;
-
- friend class TWriter;
-
- public:
- TReader()
- : ReadFrom(new TChunk())
- , ReadPosition(0)
- {
- }
-
- ~TReader() {
- while (TEntry* x = Pop()) {
- if (x->Cookie)
- x->Cookie->Detach();
- delete x->Ev;
- }
- delete ReadFrom;
- }
-
- TEntry* Pop() {
- TChunk* head = ReadFrom;
- if (ReadPosition != TChunk::EntriesCount) {
- if (AtomicLoad(&head->Entries[ReadPosition].InstantMicroseconds) != 0)
- return const_cast<TEntry*>(&head->Entries[ReadPosition++]);
- else
- return nullptr;
- } else if (TChunk* next = AtomicLoad(&head->Next)) {
- ReadFrom = next;
- delete head;
- ReadPosition = 0;
- return Pop();
- }
-
- return nullptr;
- }
- };
-
- class TWriter : ::TNonCopyable {
- TChunk* WriteTo;
- ui32 WritePosition;
-
- public:
- TWriter()
- : WriteTo(nullptr)
- , WritePosition(0)
- {
- }
-
- void Init(const TReader& reader) {
- WriteTo = reader.ReadFrom;
- WritePosition = 0;
- }
-
- void Push(ui64 instantMicrosends, IEventHandle* ev, ISchedulerCookie* cookie) {
- if (Y_UNLIKELY(instantMicrosends == 0)) {
- // Protect against Pop() getting stuck forever
- instantMicrosends = 1;
- }
- if (WritePosition != TChunk::EntriesCount) {
- volatile TEntry& entry = WriteTo->Entries[WritePosition];
- entry.Cookie = cookie;
- entry.Ev = ev;
- AtomicStore(&entry.InstantMicroseconds, instantMicrosends);
- ++WritePosition;
- } else {
- TChunk* next = new TChunk();
- volatile TEntry& entry = next->Entries[0];
- entry.Cookie = cookie;
- entry.Ev = ev;
- entry.InstantMicroseconds = instantMicrosends;
- AtomicStore(&WriteTo->Next, next);
- WriteTo = next;
- WritePosition = 1;
- }
- }
- };
-
- class TWriterWithPadding: public TWriter {
- private:
- ui8 CacheLinePadding[64 - sizeof(TWriter)];
-
- void UnusedCacheLinePadding() {
- Y_UNUSED(CacheLinePadding);
- }
- };
-
- struct TQueueType {
- TReader Reader;
- TWriter Writer;
-
- TQueueType() {
- Writer.Init(Reader);
- }
- };
- }
-}
diff --git a/library/cpp/actors/core/servicemap.h b/library/cpp/actors/core/servicemap.h
deleted file mode 100644
index d72e50cae5..0000000000
--- a/library/cpp/actors/core/servicemap.h
+++ /dev/null
@@ -1,168 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-namespace NActors {
- // wait-free one writer multi reader hash-tree for service mapping purposes
- // on fast updates on same key - could lead to false-negatives, we don't care as such cases are broken from service-map app logic
-
- template <typename TKey, typename TValue, typename THash, ui64 BaseSize = 256 * 1024, ui64 ExtCount = 4, ui64 ExtBranching = 4>
- class TServiceMap : TNonCopyable {
- struct TEntry : TNonCopyable {
- ui32 CounterIn;
- ui32 CounterOut;
- TKey Key;
- TValue Value;
-
- TEntry()
- : CounterIn(0)
- , CounterOut(0)
- , Key()
- , Value()
- {
- }
- };
-
- struct TBranch : TNonCopyable {
- TEntry Entries[ExtCount];
- TBranch* Branches[ExtBranching];
-
- TBranch() {
- Fill(Branches, Branches + ExtBranching, (TBranch*)nullptr);
- }
- };
-
- ui32 Counter;
- TBranch* Line[BaseSize];
-
- bool ScanBranch(TBranch* branch, const TKey& key, ui64 hash, TValue& ret) {
- for (ui32 i = 0; i != ExtCount; ++i) {
- const TEntry& entry = branch->Entries[i];
- const ui32 counterIn = AtomicLoad(&entry.CounterIn);
- if (counterIn != 0 && entry.Key == key) {
- ret = entry.Value;
- const ui32 counterOut = AtomicLoad(&entry.CounterOut);
- if (counterOut == counterIn)
- return true;
- }
- }
-
- const ui64 hash0 = hash % ExtBranching;
- if (TBranch* next = AtomicLoad(branch->Branches + hash0))
- return ScanBranch(next, key, hash / ExtBranching, ret);
-
- return false;
- }
-
- void ScanZeroOld(TBranch* branch, const TKey& key, ui64 hash, TEntry** zeroEntry, TEntry*& oldEntry) {
- for (ui32 i = 0; i != ExtCount; ++i) {
- TEntry& entry = branch->Entries[i];
- if (entry.CounterIn == 0) {
- if (zeroEntry && !*zeroEntry) {
- *zeroEntry = &entry;
- if (oldEntry != nullptr)
- return;
- }
- } else {
- if (entry.Key == key) {
- oldEntry = &entry;
- if (!zeroEntry || *zeroEntry)
- return;
- }
- }
- }
-
- const ui64 hash0 = hash % ExtBranching;
- if (TBranch* next = branch->Branches[hash0]) {
- ScanZeroOld(next, key, hash / ExtBranching, zeroEntry, oldEntry);
- } else { // found tail, if zeroEntry requested, but not yet found - insert one
- if (zeroEntry && !*zeroEntry) {
- TBranch* next = new TBranch();
- *zeroEntry = next->Entries;
- AtomicStore(branch->Branches + hash0, next);
- }
- }
- }
-
- public:
- TServiceMap()
- : Counter(0)
- {
- Fill(Line, Line + BaseSize, (TBranch*)nullptr);
- }
-
- ~TServiceMap() {
- for (ui64 i = 0; i < BaseSize; ++i) {
- delete Line[i];
- }
- }
-
- TValue Find(const TKey& key) {
- THash hashOp;
- const ui64 hash = hashOp(key);
- const ui64 hash0 = hash % BaseSize;
-
- if (TBranch* branch = AtomicLoad(Line + hash0)) {
- TValue ret;
- if (ScanBranch(branch, key, hash / BaseSize, ret))
- return ret;
- }
-
- return TValue();
- }
-
- // returns true on update, false on insert
- TValue Update(const TKey& key, const TValue& value) {
- THash hashOp;
- const ui64 hash = hashOp(key);
- const ui64 hash0 = hash % BaseSize;
-
- TEntry* zeroEntry = nullptr;
- TEntry* oldEntry = nullptr;
-
- if (TBranch* branch = Line[hash0]) {
- ScanZeroOld(branch, key, hash / BaseSize, &zeroEntry, oldEntry);
- } else {
- TBranch* next = new TBranch();
- zeroEntry = next->Entries;
- AtomicStore(Line + hash0, next);
- }
-
- // now we got both entries, first - push new one
- const ui32 counter = AtomicUi32Increment(&Counter);
- AtomicStore(&zeroEntry->CounterOut, counter);
- zeroEntry->Key = key;
- zeroEntry->Value = value;
- AtomicStore(&zeroEntry->CounterIn, counter);
-
- if (oldEntry != nullptr) {
- const TValue ret = oldEntry->Value;
- AtomicStore<ui32>(&oldEntry->CounterOut, 0);
- AtomicStore<ui32>(&oldEntry->CounterIn, 0);
- return ret;
- } else {
- return TValue();
- }
- }
-
- bool Erase(const TKey& key) {
- THash hashOp;
- const ui64 hash = hashOp(key);
- const ui64 hash0 = hash % BaseSize;
-
- TEntry* oldEntry = 0;
-
- if (TBranch* branch = Line[hash0]) {
- ScanZeroOld(branch, key, hash / BaseSize, 0, oldEntry);
- }
-
- if (oldEntry != 0) {
- AtomicStore<ui32>(&oldEntry->CounterOut, 0);
- AtomicStore<ui32>(&oldEntry->CounterIn, 0);
- return true;
- } else {
- return false;
- }
- }
- };
-}
diff --git a/library/cpp/actors/core/thread_context.h b/library/cpp/actors/core/thread_context.h
deleted file mode 100644
index 13e493f855..0000000000
--- a/library/cpp/actors/core/thread_context.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-#include <util/system/tls.h>
-
-
-namespace NActors {
-
- class IExecutorPool;
-
- template <typename T>
- struct TWaitingStats;
-
- struct TThreadContext {
- IExecutorPool *Pool = nullptr;
- ui32 CapturedActivation = 0;
- ESendingType CapturedType = ESendingType::Lazy;
- ESendingType SendingType = ESendingType::Common;
- bool IsEnoughCpu = true;
- ui32 WriteTurn = 0;
- TWorkerId WorkerId;
- ui16 LocalQueueSize = 0;
- TWaitingStats<ui64> *WaitingStats = nullptr;
- bool IsCurrentRecipientAService = false;
- };
-
- extern Y_POD_THREAD(TThreadContext*) TlsThreadContext; // in actor.cpp
-
-}
diff --git a/library/cpp/actors/core/tsan.supp b/library/cpp/actors/core/tsan.supp
deleted file mode 100644
index ca5be0c0f0..0000000000
--- a/library/cpp/actors/core/tsan.supp
+++ /dev/null
@@ -1,3 +0,0 @@
-# tsan reports potential deadlock which is false-positive.
-# See: https://github.com/google/sanitizers/issues/814
-deadlock:NActors::TActorCoro::StateFunc
diff --git a/library/cpp/actors/core/ut/CMakeLists.darwin-arm64.txt b/library/cpp/actors/core/ut/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 83199b12b6..0000000000
--- a/library/cpp/actors/core/ut/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,88 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-core-ut)
-target_include_directories(library-cpp-actors-core-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core
-)
-target_link_libraries(library-cpp-actors-core-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-core-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-core-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_coroutine_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/benchmark_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorsystem_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/performance_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ask_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/balancer_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb_payload_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_basic_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_united_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/mon_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-core-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-core-ut
- TEST_TARGET
- library-cpp-actors-core-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-core-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-core-ut)
diff --git a/library/cpp/actors/core/ut/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/core/ut/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index e56713f557..0000000000
--- a/library/cpp/actors/core/ut/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-core-ut)
-target_include_directories(library-cpp-actors-core-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core
-)
-target_link_libraries(library-cpp-actors-core-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-core-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-core-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_coroutine_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/benchmark_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorsystem_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/performance_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ask_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/balancer_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb_payload_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_basic_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_united_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/mon_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-core-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-core-ut
- TEST_TARGET
- library-cpp-actors-core-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-core-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-core-ut)
diff --git a/library/cpp/actors/core/ut/CMakeLists.linux-aarch64.txt b/library/cpp/actors/core/ut/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index bfd1f0f226..0000000000
--- a/library/cpp/actors/core/ut/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-core-ut)
-target_include_directories(library-cpp-actors-core-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core
-)
-target_link_libraries(library-cpp-actors-core-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-core-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-core-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_coroutine_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/benchmark_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorsystem_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/performance_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ask_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/balancer_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb_payload_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_basic_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_united_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/mon_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-core-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-core-ut
- TEST_TARGET
- library-cpp-actors-core-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-core-ut
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-core-ut)
diff --git a/library/cpp/actors/core/ut/CMakeLists.linux-x86_64.txt b/library/cpp/actors/core/ut/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 145a291b45..0000000000
--- a/library/cpp/actors/core/ut/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-core-ut)
-target_include_directories(library-cpp-actors-core-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core
-)
-target_link_libraries(library-cpp-actors-core-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-core-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-core-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_coroutine_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/benchmark_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorsystem_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/performance_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ask_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/balancer_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb_payload_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_basic_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_united_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/mon_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-core-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-core-ut
- TEST_TARGET
- library-cpp-actors-core-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-core-ut
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-core-ut)
diff --git a/library/cpp/actors/core/ut/CMakeLists.txt b/library/cpp/actors/core/ut/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/core/ut/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/core/ut/CMakeLists.windows-x86_64.txt b/library/cpp/actors/core/ut/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 8e7e6bd499..0000000000
--- a/library/cpp/actors/core/ut/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-core-ut)
-target_include_directories(library-cpp-actors-core-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core
-)
-target_link_libraries(library-cpp-actors-core-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- cpp-actors-testlib
-)
-target_sources(library-cpp-actors-core-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_coroutine_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/benchmark_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actor_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/actorsystem_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/performance_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ask_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/balancer_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb_payload_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/event_pb_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_basic_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/executor_pool_united_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/mon_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/scheduler_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-core-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-core-ut
- TEST_TARGET
- library-cpp-actors-core-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-core-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-core-ut)
diff --git a/library/cpp/actors/core/ut/ya.make b/library/cpp/actors/core/ut/ya.make
deleted file mode 100644
index 44803e7619..0000000000
--- a/library/cpp/actors/core/ut/ya.make
+++ /dev/null
@@ -1,43 +0,0 @@
-UNITTEST_FOR(library/cpp/actors/core)
-
-FORK_SUBTESTS()
-IF (SANITIZER_TYPE)
- SIZE(LARGE)
- TIMEOUT(1200)
- TAG(ya:fat)
- SPLIT_FACTOR(20)
- REQUIREMENTS(
- ram:32
- )
-ELSE()
- SIZE(MEDIUM)
- TIMEOUT(600)
- REQUIREMENTS(
- ram:16
- )
-ENDIF()
-
-
-PEERDIR(
- library/cpp/actors/interconnect
- library/cpp/actors/testlib
-)
-
-SRCS(
- actor_coroutine_ut.cpp
- benchmark_ut.cpp
- actor_ut.cpp
- actorsystem_ut.cpp
- performance_ut.cpp
- ask_ut.cpp
- balancer_ut.cpp
- event_pb_payload_ut.cpp
- event_pb_ut.cpp
- executor_pool_basic_ut.cpp
- executor_pool_united_ut.cpp
- log_ut.cpp
- mon_ut.cpp
- scheduler_actor_ut.cpp
-)
-
-END()
diff --git a/library/cpp/actors/core/ut_fat/CMakeLists.darwin-arm64.txt b/library/cpp/actors/core/ut_fat/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index c5420870b1..0000000000
--- a/library/cpp/actors/core/ut_fat/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-core-ut_fat)
-target_link_libraries(library-cpp-actors-core-ut_fat PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-core-ut_fat PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-core-ut_fat PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ut_fat/actor_benchmark.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-core-ut_fat
- PROPERTY
- SPLIT_FACTOR
- 20
-)
-add_yunittest(
- NAME
- library-cpp-actors-core-ut_fat
- TEST_TARGET
- library-cpp-actors-core-ut_fat
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- LABELS
- LARGE
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- TIMEOUT
- 1200
-)
-target_allocator(library-cpp-actors-core-ut_fat
- system_allocator
-)
-vcs_info(library-cpp-actors-core-ut_fat)
diff --git a/library/cpp/actors/core/ut_fat/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/core/ut_fat/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 88a9860fc1..0000000000
--- a/library/cpp/actors/core/ut_fat/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-core-ut_fat)
-target_link_libraries(library-cpp-actors-core-ut_fat PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-core-ut_fat PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-core-ut_fat PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ut_fat/actor_benchmark.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-core-ut_fat
- PROPERTY
- SPLIT_FACTOR
- 20
-)
-add_yunittest(
- NAME
- library-cpp-actors-core-ut_fat
- TEST_TARGET
- library-cpp-actors-core-ut_fat
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- LABELS
- LARGE
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- TIMEOUT
- 1200
-)
-target_allocator(library-cpp-actors-core-ut_fat
- system_allocator
-)
-vcs_info(library-cpp-actors-core-ut_fat)
diff --git a/library/cpp/actors/core/ut_fat/CMakeLists.linux-aarch64.txt b/library/cpp/actors/core/ut_fat/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 653d98fe60..0000000000
--- a/library/cpp/actors/core/ut_fat/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-core-ut_fat)
-target_link_libraries(library-cpp-actors-core-ut_fat PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-core-ut_fat PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-core-ut_fat PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ut_fat/actor_benchmark.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-core-ut_fat
- PROPERTY
- SPLIT_FACTOR
- 20
-)
-add_yunittest(
- NAME
- library-cpp-actors-core-ut_fat
- TEST_TARGET
- library-cpp-actors-core-ut_fat
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- LABELS
- LARGE
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- TIMEOUT
- 1200
-)
-target_allocator(library-cpp-actors-core-ut_fat
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-core-ut_fat)
diff --git a/library/cpp/actors/core/ut_fat/CMakeLists.linux-x86_64.txt b/library/cpp/actors/core/ut_fat/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index e929e6f394..0000000000
--- a/library/cpp/actors/core/ut_fat/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-core-ut_fat)
-target_link_libraries(library-cpp-actors-core-ut_fat PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-core-ut_fat PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-core-ut_fat PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ut_fat/actor_benchmark.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-core-ut_fat
- PROPERTY
- SPLIT_FACTOR
- 20
-)
-add_yunittest(
- NAME
- library-cpp-actors-core-ut_fat
- TEST_TARGET
- library-cpp-actors-core-ut_fat
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- LABELS
- LARGE
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- TIMEOUT
- 1200
-)
-target_allocator(library-cpp-actors-core-ut_fat
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-core-ut_fat)
diff --git a/library/cpp/actors/core/ut_fat/CMakeLists.txt b/library/cpp/actors/core/ut_fat/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/core/ut_fat/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/core/ut_fat/CMakeLists.windows-x86_64.txt b/library/cpp/actors/core/ut_fat/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index cd693cd949..0000000000
--- a/library/cpp/actors/core/ut_fat/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-core-ut_fat)
-target_link_libraries(library-cpp-actors-core-ut_fat PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
-)
-target_sources(library-cpp-actors-core-ut_fat PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/core/ut_fat/actor_benchmark.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-core-ut_fat
- PROPERTY
- SPLIT_FACTOR
- 20
-)
-add_yunittest(
- NAME
- library-cpp-actors-core-ut_fat
- TEST_TARGET
- library-cpp-actors-core-ut_fat
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- LABELS
- LARGE
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-core-ut_fat
- PROPERTY
- TIMEOUT
- 1200
-)
-target_allocator(library-cpp-actors-core-ut_fat
- system_allocator
-)
-vcs_info(library-cpp-actors-core-ut_fat)
diff --git a/library/cpp/actors/core/ut_fat/actor_benchmark.cpp b/library/cpp/actors/core/ut_fat/actor_benchmark.cpp
deleted file mode 100644
index d47cae6ebb..0000000000
--- a/library/cpp/actors/core/ut_fat/actor_benchmark.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-#include <library/cpp/actors/core/actor_benchmark_helper.h>
-
-#include <library/cpp/testing/unittest/registar.h>
-
-
-using namespace NActors;
-using namespace NActors::NTests;
-
-
-struct THeavyActorBenchmarkSettings : TActorBenchmarkSettings {
- static constexpr ui32 TotalEventsAmountPerThread = 1'000'000;
-
- static constexpr auto MailboxTypes = {
- TMailboxType::HTSwap,
- };
-};
-
-
-Y_UNIT_TEST_SUITE(HeavyActorBenchmark) {
-
- using TActorBenchmark = ::NActors::NTests::TActorBenchmark<THeavyActorBenchmarkSettings>;
- using TSettings = TActorBenchmark::TSettings;
-
-
- Y_UNIT_TEST(SendActivateReceiveCSV) {
- std::vector<ui32> threadsList;
- for (ui32 threads = 1; threads <= 28; threads++) {
- threadsList.push_back(threads);
- }
- std::vector<ui32> actorPairsList = {512};
- TActorBenchmark::RunSendActivateReceiveCSV(threadsList, actorPairsList, {1,100, 200}, TDuration::Seconds(1));
- }
-
- Y_UNIT_TEST(StarSendActivateReceiveCSV) {
- std::vector<ui32> threadsList;
- for (ui32 threads = 1; threads <= 28; threads++) {
- threadsList.push_back(threads);
- }
- std::vector<ui32> actorPairsList = {512};
- std::vector<ui32> starsList = {10};
- TActorBenchmark::RunStarSendActivateReceiveCSV(threadsList, actorPairsList, starsList);
- }
-
-}
diff --git a/library/cpp/actors/core/ut_fat/ya.make b/library/cpp/actors/core/ut_fat/ya.make
deleted file mode 100644
index 937e59720d..0000000000
--- a/library/cpp/actors/core/ut_fat/ya.make
+++ /dev/null
@@ -1,32 +0,0 @@
-UNITTEST()
-
-FORK_SUBTESTS()
-
-IF (SANITIZER_TYPE)
- SIZE(LARGE)
- TIMEOUT(2400)
- TAG(ya:fat)
- SPLIT_FACTOR(20)
- REQUIREMENTS(
- ram:32
- )
-ELSE()
- SIZE(LARGE)
- TIMEOUT(1200)
- TAG(ya:fat)
- SPLIT_FACTOR(20)
- REQUIREMENTS(
- ram:16
- )
-ENDIF()
-
-
-PEERDIR(
- library/cpp/actors/core
-)
-
-SRCS(
- actor_benchmark.cpp
-)
-
-END()
diff --git a/library/cpp/actors/core/worker_context.cpp b/library/cpp/actors/core/worker_context.cpp
deleted file mode 100644
index ada6c997d4..0000000000
--- a/library/cpp/actors/core/worker_context.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "worker_context.h"
-#include "probes.h"
-
-namespace NActors {
- LWTRACE_USING(ACTORLIB_PROVIDER);
-
-}
diff --git a/library/cpp/actors/core/worker_context.h b/library/cpp/actors/core/worker_context.h
deleted file mode 100644
index b51ff55cd3..0000000000
--- a/library/cpp/actors/core/worker_context.h
+++ /dev/null
@@ -1,192 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-//#include "actorsystem.h"
-#include "event.h"
-#include "executor_pool.h"
-#include "lease.h"
-#include "mailbox.h"
-#include "mon_stats.h"
-
-#include <library/cpp/actors/util/cpumask.h>
-#include <library/cpp/actors/util/datetime.h>
-#include <library/cpp/actors/util/intrinsics.h>
-#include <library/cpp/actors/util/thread.h>
-
-#include <library/cpp/lwtrace/shuttle.h>
-
-namespace NActors {
- struct TWorkerContext {
- TWorkerId WorkerId;
- const TCpuId CpuId;
- TLease Lease;
- IExecutorPool* Executor = nullptr;
- TMailboxTable* MailboxTable = nullptr;
- ui64 TimePerMailboxTs = 0;
- ui32 EventsPerMailbox = 0;
- ui64 SoftDeadlineTs = ui64(-1);
- TExecutorThreadStats* Stats = &WorkerStats; // pool stats
- TExecutorThreadStats WorkerStats;
- TPoolId PoolId = MaxPools;
- mutable NLWTrace::TOrbit Orbit;
- bool IsNeededToWaitNextActivation = true;
- i64 HPStart = 0;
- ui32 ExecutedEvents = 0;
-
- TWorkerContext(TWorkerId workerId, TCpuId cpuId)
- : WorkerId(workerId)
- , CpuId(cpuId)
- , Lease(WorkerId, NeverExpire)
- {}
-
-#ifdef ACTORSLIB_COLLECT_EXEC_STATS
- void GetCurrentStats(TExecutorThreadStats& statsCopy) const {
- statsCopy = TExecutorThreadStats();
- statsCopy.Aggregate(*Stats);
- }
-
- void AddElapsedCycles(ui32 activityType, i64 elapsed) {
- Y_DEBUG_ABORT_UNLESS(activityType < Stats->MaxActivityType());
- RelaxedStore(&Stats->ElapsedTicks, RelaxedLoad(&Stats->ElapsedTicks) + elapsed);
- RelaxedStore(&Stats->ElapsedTicksByActivity[activityType], RelaxedLoad(&Stats->ElapsedTicksByActivity[activityType]) + elapsed);
- }
-
- void AddParkedCycles(i64 elapsed) {
- RelaxedStore(&Stats->ParkedTicks, RelaxedLoad(&Stats->ParkedTicks) + elapsed);
- }
-
- void AddBlockedCycles(i64 elapsed) {
- RelaxedStore(&Stats->BlockedTicks, RelaxedLoad(&Stats->BlockedTicks) + elapsed);
- }
-
- void IncrementSentEvents() {
- RelaxedStore(&Stats->SentEvents, RelaxedLoad(&Stats->SentEvents) + 1);
- }
-
- void IncrementPreemptedEvents() {
- RelaxedStore(&Stats->PreemptedEvents, RelaxedLoad(&Stats->PreemptedEvents) + 1);
- }
-
- void DecrementActorsAliveByActivity(ui32 activityType) {
- if (activityType >= Stats->MaxActivityType()) {
- activityType = 0;
- }
- RelaxedStore(&Stats->ActorsAliveByActivity[activityType], Stats->ActorsAliveByActivity[activityType] - 1);
- }
-
- inline void IncrementNonDeliveredEvents() {
- RelaxedStore(&Stats->NonDeliveredEvents, RelaxedLoad(&Stats->NonDeliveredEvents) + 1);
- }
-
- inline void IncrementMailboxPushedOutByTailSending() {
- RelaxedStore(&Stats->MailboxPushedOutByTailSending, RelaxedLoad(&Stats->MailboxPushedOutByTailSending) + 1);
- }
-
- inline void IncrementMailboxPushedOutBySoftPreemption() {
- RelaxedStore(&Stats->MailboxPushedOutBySoftPreemption, RelaxedLoad(&Stats->MailboxPushedOutBySoftPreemption) + 1);
- }
-
- inline void IncrementMailboxPushedOutByTime() {
- RelaxedStore(&Stats->MailboxPushedOutByTime, RelaxedLoad(&Stats->MailboxPushedOutByTime) + 1);
- }
-
- inline void IncrementMailboxPushedOutByEventCount() {
- RelaxedStore(&Stats->MailboxPushedOutByEventCount, RelaxedLoad(&Stats->MailboxPushedOutByEventCount) + 1);
- }
-
- inline void IncrementEmptyMailboxActivation() {
- RelaxedStore(&Stats->EmptyMailboxActivation, RelaxedLoad(&Stats->EmptyMailboxActivation) + 1);
- }
-
- double AddActivationStats(i64 scheduleTs, i64 deliveredTs) {
- i64 ts = deliveredTs > scheduleTs ? deliveredTs - scheduleTs : 0;
- double usec = NHPTimer::GetSeconds(ts) * 1000000.0;
- Stats->ActivationTimeHistogram.Add(usec);
- RelaxedStore(&Stats->WorstActivationTimeUs, Max(Stats->WorstActivationTimeUs, (ui64)usec));
- return usec;
- }
-
- ui64 AddEventDeliveryStats(i64 sentTs, i64 deliveredTs) {
- ui64 usecDeliv = deliveredTs > sentTs ? NHPTimer::GetSeconds(deliveredTs - sentTs) * 1000000 : 0;
- Stats->EventDeliveryTimeHistogram.Add(usecDeliv);
- return usecDeliv;
- }
-
- i64 AddEventProcessingStats(i64 deliveredTs, i64 processedTs, ui32 activityType, ui64 scheduled) {
- i64 elapsed = processedTs - deliveredTs;
- ui64 usecElapsed = NHPTimer::GetSeconds(elapsed) * 1000000;
- activityType = (activityType >= Stats->MaxActivityType()) ? 0 : activityType;
- Stats->EventProcessingCountHistogram.Add(usecElapsed);
- Stats->EventProcessingTimeHistogram.Add(usecElapsed, elapsed);
- RelaxedStore(&Stats->ReceivedEvents, RelaxedLoad(&Stats->ReceivedEvents) + 1);
- RelaxedStore(&Stats->ReceivedEventsByActivity[activityType], RelaxedLoad(&Stats->ReceivedEventsByActivity[activityType]) + 1);
- RelaxedStore(&Stats->ScheduledEventsByActivity[activityType], RelaxedLoad(&Stats->ScheduledEventsByActivity[activityType]) + scheduled);
- AddElapsedCycles(activityType, elapsed);
- return elapsed;
- }
-
- void UpdateActorsStats(size_t dyingActorsCnt) {
- if (dyingActorsCnt) {
- AtomicAdd(Executor->DestroyedActors, dyingActorsCnt);
- }
- RelaxedStore(&Stats->PoolDestroyedActors, (ui64)RelaxedLoad(&Executor->DestroyedActors));
- RelaxedStore(&Stats->PoolActorRegistrations, (ui64)RelaxedLoad(&Executor->ActorRegistrations));
- RelaxedStore(&Stats->PoolAllocatedMailboxes, MailboxTable->GetAllocatedMailboxCount());
- }
-
- void UpdateThreadTime() {
- RelaxedStore(&WorkerStats.SafeElapsedTicks, (ui64)RelaxedLoad(&WorkerStats.ElapsedTicks));
- RelaxedStore(&WorkerStats.CpuUs, ThreadCPUTime());
- }
-
- void IncreaseNotEnoughCpuExecutions() {
- RelaxedStore(&WorkerStats.NotEnoughCpuExecutions,
- (ui64)RelaxedLoad(&WorkerStats.NotEnoughCpuExecutions) + 1);
- }
-#else
- void GetCurrentStats(TExecutorThreadStats&) const {}
- inline void AddElapsedCycles(ui32, i64) {}
- inline void AddParkedCycles(i64) {}
- inline void AddBlockedCycles(i64) {}
- inline void IncrementSentEvents() {}
- inline void IncrementPreemptedEvents() {}
- inline void IncrementMailboxPushedOutByTailSending() {}
- inline void IncrementMailboxPushedOutBySoftPreemption() {}
- inline void IncrementMailboxPushedOutByTime() {}
- inline void IncrementMailboxPushedOutByEventCount() {}
- inline void IncrementEmptyMailboxActivation() {}
- void DecrementActorsAliveByActivity(ui32) {}
- void IncrementNonDeliveredEvents() {}
- double AddActivationStats(i64, i64) { return 0; }
- ui64 AddEventDeliveryStats(i64, i64) { return 0; }
- i64 AddEventProcessingStats(i64, i64, ui32, ui64) { return 0; }
- void UpdateActorsStats(size_t, IExecutorPool*) {}
- void UpdateThreadTime() {}
- void IncreaseNotEnoughCpuExecutions() {}
-#endif
-
- void Switch(IExecutorPool* executor,
- TMailboxTable* mailboxTable,
- ui64 timePerMailboxTs,
- ui32 eventsPerMailbox,
- ui64 softDeadlineTs,
- TExecutorThreadStats* stats)
- {
- Executor = executor;
- MailboxTable = mailboxTable;
- TimePerMailboxTs = timePerMailboxTs;
- EventsPerMailbox = eventsPerMailbox;
- SoftDeadlineTs = softDeadlineTs;
- Stats = stats;
- PoolId = Executor ? Executor->PoolId : MaxPools;
- }
-
- void SwitchToIdle() {
- Executor = nullptr;
- MailboxTable = nullptr;
- //Stats = &WorkerStats; // TODO: in actorsystem 2.0 idle stats cannot be related to specific pool
- PoolId = MaxPools;
- }
- };
-}
diff --git a/library/cpp/actors/core/ya.make b/library/cpp/actors/core/ya.make
deleted file mode 100644
index 8dadea5fdc..0000000000
--- a/library/cpp/actors/core/ya.make
+++ /dev/null
@@ -1,133 +0,0 @@
-LIBRARY()
-
-NO_WSHADOW()
-
-IF (PROFILE_MEMORY_ALLOCATIONS)
- CFLAGS(-DPROFILE_MEMORY_ALLOCATIONS)
-ENDIF()
-
-IF (ALLOCATOR == "B" OR ALLOCATOR == "BS" OR ALLOCATOR == "C")
- CXXFLAGS(-DBALLOC)
- PEERDIR(
- library/cpp/balloc/optional
- )
-ENDIF()
-
-SRCS(
- actor_bootstrapped.cpp
- actor_coroutine.cpp
- actor_coroutine.h
- actor.cpp
- actor.h
- actor_virtual.cpp
- actorid.cpp
- actorid.h
- actorsystem.cpp
- actorsystem.h
- ask.cpp
- ask.h
- av_bootstrapped.cpp
- balancer.h
- balancer.cpp
- buffer.cpp
- buffer.h
- callstack.cpp
- callstack.h
- config.h
- cpu_manager.cpp
- cpu_manager.h
- cpu_state.h
- defs.h
- event.cpp
- event.h
- event_load.cpp
- event_local.h
- event_pb.cpp
- event_pb.h
- events.h
- events_undelivered.cpp
- executelater.h
- executor_pool_base.cpp
- executor_pool_base.h
- executor_pool_basic.cpp
- executor_pool_basic.h
- executor_pool_io.cpp
- executor_pool_io.h
- executor_pool_united.cpp
- executor_pool_united.h
- executor_thread.cpp
- executor_thread.h
- harmonizer.cpp
- harmonizer.h
- hfunc.h
- interconnect.cpp
- interconnect.h
- invoke.h
- io_dispatcher.cpp
- io_dispatcher.h
- lease.h
- log.cpp
- log.h
- log_settings.cpp
- log_settings.h
- log_buffer.cpp
- log_buffer.h
- log_metrics.h
- mailbox.cpp
- mailbox.h
- mailbox_queue_revolving.h
- mailbox_queue_simple.h
- mon.h
- mon_stats.h
- monotonic.cpp
- monotonic.h
- monotonic_provider.cpp
- monotonic_provider.h
- worker_context.cpp
- worker_context.h
- probes.cpp
- probes.h
- process_stats.cpp
- process_stats.h
- scheduler_actor.cpp
- scheduler_actor.h
- scheduler_basic.cpp
- scheduler_basic.h
- scheduler_cookie.cpp
- scheduler_cookie.h
- scheduler_queue.h
- servicemap.h
-)
-
-GENERATE_ENUM_SERIALIZATION(defs.h)
-GENERATE_ENUM_SERIALIZATION(actor.h)
-GENERATE_ENUM_SERIALIZATION(log_iface.h)
-
-PEERDIR(
- library/cpp/actors/actor_type
- library/cpp/actors/memory_log
- library/cpp/actors/prof
- library/cpp/actors/protos
- library/cpp/actors/util
- library/cpp/execprofile
- library/cpp/json/writer
- library/cpp/logger
- library/cpp/lwtrace
- library/cpp/monlib/dynamic_counters
- library/cpp/svnversion
- library/cpp/time_provider
- library/cpp/threading/future
-)
-
-IF (SANITIZER_TYPE == "thread")
- SUPPRESSIONS(
- tsan.supp
- )
-ENDIF()
-
-END()
-
-RECURSE_FOR_TESTS(
- ut
- ut_fat
-)
diff --git a/library/cpp/actors/cppcoro/CMakeLists.darwin-arm64.txt b/library/cpp/actors/cppcoro/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 9795130141..0000000000
--- a/library/cpp/actors/cppcoro/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(corobenchmark)
-add_subdirectory(ut)
-
-add_library(cpp-actors-cppcoro)
-target_link_libraries(cpp-actors-cppcoro PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
-)
-target_sources(cpp-actors-cppcoro PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/await_callback.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_group.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_result.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task.cpp
-)
diff --git a/library/cpp/actors/cppcoro/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/cppcoro/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 9795130141..0000000000
--- a/library/cpp/actors/cppcoro/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(corobenchmark)
-add_subdirectory(ut)
-
-add_library(cpp-actors-cppcoro)
-target_link_libraries(cpp-actors-cppcoro PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
-)
-target_sources(cpp-actors-cppcoro PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/await_callback.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_group.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_result.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task.cpp
-)
diff --git a/library/cpp/actors/cppcoro/CMakeLists.linux-aarch64.txt b/library/cpp/actors/cppcoro/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 514824dad2..0000000000
--- a/library/cpp/actors/cppcoro/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(corobenchmark)
-add_subdirectory(ut)
-
-add_library(cpp-actors-cppcoro)
-target_link_libraries(cpp-actors-cppcoro PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
-)
-target_sources(cpp-actors-cppcoro PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/await_callback.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_group.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_result.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task.cpp
-)
diff --git a/library/cpp/actors/cppcoro/CMakeLists.linux-x86_64.txt b/library/cpp/actors/cppcoro/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 514824dad2..0000000000
--- a/library/cpp/actors/cppcoro/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(corobenchmark)
-add_subdirectory(ut)
-
-add_library(cpp-actors-cppcoro)
-target_link_libraries(cpp-actors-cppcoro PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
-)
-target_sources(cpp-actors-cppcoro PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/await_callback.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_group.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_result.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task.cpp
-)
diff --git a/library/cpp/actors/cppcoro/CMakeLists.txt b/library/cpp/actors/cppcoro/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/cppcoro/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/cppcoro/CMakeLists.windows-x86_64.txt b/library/cpp/actors/cppcoro/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 9795130141..0000000000
--- a/library/cpp/actors/cppcoro/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(corobenchmark)
-add_subdirectory(ut)
-
-add_library(cpp-actors-cppcoro)
-target_link_libraries(cpp-actors-cppcoro PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
-)
-target_sources(cpp-actors-cppcoro PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/await_callback.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_group.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_result.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task.cpp
-)
diff --git a/library/cpp/actors/cppcoro/await_callback.cpp b/library/cpp/actors/cppcoro/await_callback.cpp
deleted file mode 100644
index 5132131a8e..0000000000
--- a/library/cpp/actors/cppcoro/await_callback.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "await_callback.h"
diff --git a/library/cpp/actors/cppcoro/await_callback.h b/library/cpp/actors/cppcoro/await_callback.h
deleted file mode 100644
index fcb2eb78f9..0000000000
--- a/library/cpp/actors/cppcoro/await_callback.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#include <coroutine>
-#include <exception>
-#include <concepts>
-
-namespace NActors {
-
- namespace NDetail {
-
- template<class TAwaitable>
- decltype(auto) GetAwaiter(TAwaitable&& awaitable) {
- if constexpr (requires { ((TAwaitable&&) awaitable).operator co_await(); }) {
- return ((TAwaitable&&) awaitable).operator co_await();
- } else if constexpr (requires { operator co_await((TAwaitable&&) awaitable); }) {
- return operator co_await((TAwaitable&&) awaitable);
- } else {
- return ((TAwaitable&&) awaitable);
- }
- }
-
- template<class TAwaitable>
- using TAwaitResult = decltype(GetAwaiter(std::declval<TAwaitable>()).await_resume());
-
- template<class TCallback, class TResult>
- class TCallbackResult {
- public:
- TCallbackResult(TCallback& callback)
- : Callback(callback)
- {}
-
- template<class TRealResult>
- void return_value(TRealResult&& result) noexcept {
- Callback(std::forward<TRealResult>(result));
- }
-
- private:
- TCallback& Callback;
- };
-
- template<class TCallback>
- class TCallbackResult<TCallback, void> {
- public:
- TCallbackResult(TCallback& callback)
- : Callback(callback)
- {}
-
- void return_void() noexcept {
- Callback();
- }
-
- private:
- TCallback& Callback;
- };
-
- template<class TAwaitable, class TCallback>
- class TAwaitThenCallbackPromise
- : public TCallbackResult<TCallback, TAwaitResult<TAwaitable>>
- {
- public:
- using THandle = std::coroutine_handle<TAwaitThenCallbackPromise<TAwaitable, TCallback>>;
-
- TAwaitThenCallbackPromise(TAwaitable&, TCallback& callback)
- : TCallbackResult<TCallback, TAwaitResult<TAwaitable>>(callback)
- {}
-
- THandle get_return_object() noexcept {
- return THandle::from_promise(*this);
- }
-
- static auto initial_suspend() noexcept { return std::suspend_never{}; }
- static auto final_suspend() noexcept { return std::suspend_never{}; }
-
- void unhandled_exception() noexcept {
- std::terminate();
- }
- };
-
- template<class TAwaitable, class TCallback>
- class TAwaitThenCallback {
- public:
- using promise_type = TAwaitThenCallbackPromise<TAwaitable, TCallback>;
-
- using THandle = typename promise_type::THandle;
-
- TAwaitThenCallback(THandle) noexcept {}
- };
-
- } // namespace NDetail
-
- /**
- * Awaits the awaitable and calls callback with the result.
- *
- * Note: program terminates if awaitable or callback throw an exception.
- */
- template<class TAwaitable, class TCallback>
- NDetail::TAwaitThenCallback<TAwaitable, TCallback> AwaitThenCallback(TAwaitable awaitable, TCallback) {
- // Note: underlying promise takes callback argument address and calls it when we return
- co_return co_await std::move(awaitable);
- }
-
-} // namespace NActors
diff --git a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.darwin-arm64.txt b/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 1043b6f834..0000000000
--- a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(corobenchmark)
-target_link_libraries(corobenchmark PUBLIC
- contrib-libs-cxxsupp
- yutil
- testing-benchmark-main
- cpp-actors-cppcoro
-)
-target_link_options(corobenchmark PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(corobenchmark PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/corobenchmark/main.cpp
-)
-target_allocator(corobenchmark
- system_allocator
-)
-vcs_info(corobenchmark)
diff --git a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 1b98f8aac0..0000000000
--- a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(corobenchmark)
-target_link_libraries(corobenchmark PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- testing-benchmark-main
- cpp-actors-cppcoro
-)
-target_link_options(corobenchmark PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(corobenchmark PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/corobenchmark/main.cpp
-)
-target_allocator(corobenchmark
- system_allocator
-)
-vcs_info(corobenchmark)
diff --git a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.linux-aarch64.txt b/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index f12dfdad8d..0000000000
--- a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(corobenchmark)
-target_link_libraries(corobenchmark PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- testing-benchmark-main
- cpp-actors-cppcoro
-)
-target_link_options(corobenchmark PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(corobenchmark PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/corobenchmark/main.cpp
-)
-target_allocator(corobenchmark
- cpp-malloc-jemalloc
-)
-vcs_info(corobenchmark)
diff --git a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.linux-x86_64.txt b/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index e5b37926d1..0000000000
--- a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(corobenchmark)
-target_link_libraries(corobenchmark PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- testing-benchmark-main
- cpp-actors-cppcoro
-)
-target_link_options(corobenchmark PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(corobenchmark PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/corobenchmark/main.cpp
-)
-target_allocator(corobenchmark
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(corobenchmark)
diff --git a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.txt b/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.windows-x86_64.txt b/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index c9a8359b4b..0000000000
--- a/library/cpp/actors/cppcoro/corobenchmark/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(corobenchmark)
-target_link_libraries(corobenchmark PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- testing-benchmark-main
- cpp-actors-cppcoro
-)
-target_sources(corobenchmark PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/corobenchmark/main.cpp
-)
-target_allocator(corobenchmark
- system_allocator
-)
-vcs_info(corobenchmark)
diff --git a/library/cpp/actors/cppcoro/corobenchmark/main.cpp b/library/cpp/actors/cppcoro/corobenchmark/main.cpp
deleted file mode 100644
index 49504e7105..0000000000
--- a/library/cpp/actors/cppcoro/corobenchmark/main.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <library/cpp/actors/cppcoro/task.h>
-#include <library/cpp/actors/cppcoro/await_callback.h>
-#include <library/cpp/testing/benchmark/bench.h>
-
-using namespace NActors;
-
-namespace {
-
- int LastValue = 0;
-
- Y_NO_INLINE int NextFuncValue() {
- return ++LastValue;
- }
-
- Y_NO_INLINE void IterateFuncValues(size_t iterations) {
- for (size_t i = 0; i < iterations; ++i) {
- int value = NextFuncValue();
- Y_DO_NOT_OPTIMIZE_AWAY(value);
- }
- }
-
- Y_NO_INLINE TTask<int> NextTaskValue() {
- co_return ++LastValue;
- }
-
- Y_NO_INLINE TTask<void> IterateTaskValues(size_t iterations) {
- for (size_t i = 0; i < iterations; ++i) {
- int value = co_await NextTaskValue();
- Y_DO_NOT_OPTIMIZE_AWAY(value);
- }
- }
-
- std::coroutine_handle<> Paused;
-
- struct {
- static bool await_ready() noexcept {
- return false;
- }
- static void await_suspend(std::coroutine_handle<> h) noexcept {
- Paused = h;
- }
- static int await_resume() noexcept {
- return ++LastValue;
- }
- } Pause;
-
- Y_NO_INLINE TTask<void> IteratePauseValues(size_t iterations) {
- for (size_t i = 0; i < iterations; ++i) {
- int value = co_await Pause;
- Y_DO_NOT_OPTIMIZE_AWAY(value);
- }
- }
-
-} // namespace
-
-Y_CPU_BENCHMARK(FuncCalls, iface) {
- IterateFuncValues(iface.Iterations());
-}
-
-Y_CPU_BENCHMARK(TaskCalls, iface) {
- bool finished = false;
- AwaitThenCallback(IterateTaskValues(iface.Iterations()), [&]{
- finished = true;
- });
- Y_ABORT_UNLESS(finished);
-}
-
-Y_CPU_BENCHMARK(CoroAwaits, iface) {
- bool finished = false;
- AwaitThenCallback(IteratePauseValues(iface.Iterations()), [&]{
- finished = true;
- });
- while (!finished) {
- std::exchange(Paused, {}).resume();
- }
-}
diff --git a/library/cpp/actors/cppcoro/corobenchmark/ya.make b/library/cpp/actors/cppcoro/corobenchmark/ya.make
deleted file mode 100644
index ef5ad4135c..0000000000
--- a/library/cpp/actors/cppcoro/corobenchmark/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-Y_BENCHMARK()
-
-PEERDIR(
- library/cpp/actors/cppcoro
-)
-
-SRCS(
- main.cpp
-)
-
-END()
diff --git a/library/cpp/actors/cppcoro/task.cpp b/library/cpp/actors/cppcoro/task.cpp
deleted file mode 100644
index 204c27c573..0000000000
--- a/library/cpp/actors/cppcoro/task.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "task.h"
diff --git a/library/cpp/actors/cppcoro/task.h b/library/cpp/actors/cppcoro/task.h
deleted file mode 100644
index bb5a385db2..0000000000
--- a/library/cpp/actors/cppcoro/task.h
+++ /dev/null
@@ -1,228 +0,0 @@
-#pragma once
-#include "task_result.h"
-#include <util/system/yassert.h>
-#include <coroutine>
-#include <utility>
-
-namespace NActors {
-
- template<class T>
- class TTask;
-
- /**
- * This exception is commonly thrown when task is cancelled
- */
- class TTaskCancelled : public std::exception {
- public:
- const char* what() const noexcept {
- return "Task cancelled";
- }
- };
-
- namespace NDetail {
-
- template<class T>
- class TTaskPromise;
-
- template<class T>
- using TTaskHandle = std::coroutine_handle<TTaskPromise<T>>;
-
- template<class T>
- class TTaskAwaiter {
- public:
- explicit TTaskAwaiter(TTaskHandle<T> handle)
- : Handle(handle)
- {
- Y_DEBUG_ABORT_UNLESS(Handle);
- }
-
- TTaskAwaiter(TTaskAwaiter&& rhs)
- : Handle(std::exchange(rhs.Handle, {}))
- {}
-
- TTaskAwaiter& operator=(const TTaskAwaiter&) = delete;
- TTaskAwaiter& operator=(TTaskAwaiter&&) = delete;
-
- ~TTaskAwaiter() noexcept {
- if (Handle) {
- Handle.destroy();
- }
- }
-
- // We can only await a task that has not started yet
- static bool await_ready() noexcept { return false; }
-
- // Some arbitrary continuation c suspended and awaits the task
- TTaskHandle<T> await_suspend(std::coroutine_handle<> c) noexcept {
- Y_DEBUG_ABORT_UNLESS(Handle);
- Handle.promise().SetContinuation(c);
- return Handle;
- }
-
- TTaskResult<T>&& await_resume() noexcept {
- Y_DEBUG_ABORT_UNLESS(Handle);
- return std::move(Handle.promise().Result);
- }
-
- private:
- TTaskHandle<T> Handle;
- };
-
- template<class T>
- class TTaskResultAwaiter final : public TTaskAwaiter<T> {
- public:
- using TTaskAwaiter<T>::TTaskAwaiter;
-
- T&& await_resume() {
- return TTaskAwaiter<T>::await_resume().Value();
- }
- };
-
- template<>
- class TTaskResultAwaiter<void> final : public TTaskAwaiter<void> {
- public:
- using TTaskAwaiter<void>::TTaskAwaiter;
-
- void await_resume() {
- TTaskAwaiter<void>::await_resume().Value();
- }
- };
-
- template<class T>
- class TTaskResultHandlerBase {
- public:
- void unhandled_exception() noexcept {
- Result.SetException(std::current_exception());
- }
-
- protected:
- TTaskResult<T> Result;
- };
-
- template<class T>
- class TTaskResultHandler : public TTaskResultHandlerBase<T> {
- public:
- template<class TResult>
- void return_value(TResult&& value) {
- this->Result.SetValue(std::forward<TResult>(value));
- }
- };
-
- template<>
- class TTaskResultHandler<void> : public TTaskResultHandlerBase<void> {
- public:
- void return_void() noexcept {
- this->Result.SetValue();
- }
- };
-
- template<class T>
- class TTaskPromise final
- : public TTaskResultHandler<T>
- {
- friend class TTaskAwaiter<T>;
-
- public:
- TTask<T> get_return_object() noexcept;
-
- static auto initial_suspend() noexcept { return std::suspend_always{}; }
-
- struct TFinalSuspend {
- static bool await_ready() noexcept { return false; }
- static void await_resume() noexcept { Y_ABORT("unexpected coroutine resume"); }
-
- static std::coroutine_handle<> await_suspend(std::coroutine_handle<TTaskPromise<T>> h) noexcept {
- auto next = std::exchange(h.promise().Continuation, std::noop_coroutine());
- Y_DEBUG_ABORT_UNLESS(next, "Task finished without a continuation");
- return next;
- }
- };
-
- static auto final_suspend() noexcept { return TFinalSuspend{}; }
-
- private:
- void SetContinuation(std::coroutine_handle<> continuation) noexcept {
- Y_DEBUG_ABORT_UNLESS(!Continuation, "Task can only be awaited once");
- Continuation = continuation;
- }
-
- private:
- std::coroutine_handle<> Continuation;
- };
-
- } // namespace NDetail
-
- /**
- * Represents a task that has not been started yet
- */
- template<class T>
- class TTask final {
- public:
- using promise_type = NDetail::TTaskPromise<T>;
- using value_type = T;
-
- public:
- TTask() noexcept = default;
-
- explicit TTask(NDetail::TTaskHandle<T> handle) noexcept
- : Handle(handle)
- {}
-
- TTask(TTask&& rhs) noexcept
- : Handle(std::exchange(rhs.Handle, {}))
- {}
-
- ~TTask() {
- if (Handle) {
- Handle.destroy();
- }
- }
-
- TTask& operator=(TTask&& rhs) noexcept {
- if (Y_LIKELY(this != &rhs)) {
- auto handle = std::exchange(Handle, {});
- Handle = std::exchange(rhs.Handle, {});
- if (handle) {
- handle.destroy();
- }
- }
- return *this;
- }
-
- /**
- * Returns true for a valid task object
- */
- explicit operator bool() const noexcept {
- return bool(Handle);
- }
-
- /**
- * Starts task and returns TTaskResult<T> when it completes
- */
- auto WhenDone() && noexcept {
- Y_DEBUG_ABORT_UNLESS(Handle, "Cannot await an empty task");
- return NDetail::TTaskAwaiter<T>(std::exchange(Handle, {}));
- }
-
- /**
- * Starts task and returns its result when it completes
- */
- auto operator co_await() && noexcept {
- Y_DEBUG_ABORT_UNLESS(Handle, "Cannot await an empty task");
- return NDetail::TTaskResultAwaiter<T>(std::exchange(Handle, {}));
- }
-
- private:
- NDetail::TTaskHandle<T> Handle;
- };
-
- namespace NDetail {
-
- template<class T>
- inline TTask<T> TTaskPromise<T>::get_return_object() noexcept {
- return TTask<T>(TTaskHandle<T>::from_promise(*this));
- }
-
- } // namespace NDetail
-
-} // namespace NActors
diff --git a/library/cpp/actors/cppcoro/task_actor.cpp b/library/cpp/actors/cppcoro/task_actor.cpp
deleted file mode 100644
index 8a9451c8e5..0000000000
--- a/library/cpp/actors/cppcoro/task_actor.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-#include "task_actor.h"
-#include "await_callback.h"
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/hfunc.h>
-
-namespace NActors {
-
- class TTaskActorImpl;
-
- static Y_POD_THREAD(TTaskActorImpl*) TlsCurrentTaskActor{nullptr};
-
- struct TCurrentTaskActorGuard {
- TCurrentTaskActorGuard(TTaskActorImpl* current) noexcept {
- Y_ABORT_UNLESS(TlsCurrentTaskActor == nullptr);
- TlsCurrentTaskActor = current;
- }
-
- ~TCurrentTaskActorGuard() noexcept {
- TlsCurrentTaskActor = nullptr;
- }
- };
-
- enum : ui32 {
- EvResumeTask = EventSpaceBegin(TEvents::ES_SYSTEM) + 256,
- };
-
- struct TEvResumeTask : public TEventLocal<TEvResumeTask, EvResumeTask> {
- std::coroutine_handle<> Handle;
- TTaskResult<void>* Result;
-
- explicit TEvResumeTask(std::coroutine_handle<> handle, TTaskResult<void>* result) noexcept
- : Handle(handle)
- , Result(result)
- {}
-
- ~TEvResumeTask() noexcept {
- if (Handle) {
- Result->SetException(std::make_exception_ptr(TTaskCancelled()));
- Handle.resume();
- }
- }
- };
-
- class TTaskActorResult final : public TAtomicRefCount<TTaskActorResult> {
- public:
- bool Finished = false;
- };
-
- class TTaskActorImpl : public TActor<TTaskActorImpl> {
- friend class TTaskActor;
- friend class TAfterAwaiter;
- friend class TBindAwaiter;
-
- public:
- TTaskActorImpl(TTask<void>&& task)
- : TActor(&TThis::StateBoot)
- , Task(std::move(task))
- {
- Y_ABORT_UNLESS(Task);
- }
-
- ~TTaskActorImpl() {
- Stopped = true;
- while (EventAwaiter) {
- // Unblock event awaiter until task stops trying
- TCurrentTaskActorGuard guard(this);
- std::exchange(EventAwaiter, {}).resume();
- }
- }
-
- void Registered(TActorSystem* sys, const TActorId& parent) override {
- ParentId = parent;
- sys->Send(new IEventHandle(TEvents::TSystem::Bootstrap, 0, SelfId(), SelfId(), {}, 0));
- }
-
- STATEFN(StateBoot) {
- Y_ABORT_UNLESS(ev->GetTypeRewrite() == TEvents::TSystem::Bootstrap, "Expected bootstrap event");
- TCurrentTaskActorGuard guard(this);
- Become(&TThis::StateWork);
- AwaitThenCallback(std::move(Task).WhenDone(),
- [result = Result](TTaskResult<void>&& outcome) noexcept {
- result->Finished = true;
- try {
- outcome.Value();
- } catch (TTaskCancelled&) {
- // ignore
- }
- });
- Check();
- }
-
- STATEFN(StateWork) {
- TCurrentTaskActorGuard guard(this);
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvResumeTask, Handle);
- default:
- Y_ABORT_UNLESS(EventAwaiter);
- Event.reset(ev.Release());
- std::exchange(EventAwaiter, {}).resume();
- }
- Check();
- }
-
- void Handle(TEvResumeTask::TPtr& ev) {
- auto* msg = ev->Get();
- msg->Result->SetValue();
- std::exchange(msg->Handle, {}).resume();
- }
-
- bool Check() {
- if (Result->Finished) {
- Y_ABORT_UNLESS(!EventAwaiter, "Task terminated while waiting for the next event");
- PassAway();
- return false;
- }
-
- Y_ABORT_UNLESS(EventAwaiter, "Task suspended without waiting for the next event");
- return true;
- }
-
- void WaitForEvent(std::coroutine_handle<> h) noexcept {
- Y_ABORT_UNLESS(!EventAwaiter, "Task cannot have multiple awaiters for the next event");
- EventAwaiter = h;
- }
-
- std::unique_ptr<IEventHandle> FinishWaitForEvent() {
- if (Stopped) {
- throw TTaskCancelled();
- }
- Y_ABORT_UNLESS(Event, "Task does not have current event");
- return std::move(Event);
- }
-
- private:
- TIntrusivePtr<TTaskActorResult> Result = MakeIntrusive<TTaskActorResult>();
- TTask<void> Task;
- TActorId ParentId;
- std::coroutine_handle<> EventAwaiter;
- std::unique_ptr<IEventHandle> Event;
- bool Stopped = false;
- };
-
- void TTaskActorNextEvent::await_suspend(std::coroutine_handle<> h) noexcept {
- Y_ABORT_UNLESS(TlsCurrentTaskActor, "Not in a task actor context");
- TlsCurrentTaskActor->WaitForEvent(h);
- }
-
- std::unique_ptr<IEventHandle> TTaskActorNextEvent::await_resume() {
- Y_ABORT_UNLESS(TlsCurrentTaskActor, "Not in a task actor context");
- return TlsCurrentTaskActor->FinishWaitForEvent();
- }
-
- IActor* TTaskActor::Create(TTask<void>&& task) {
- return new TTaskActorImpl(std::move(task));
- }
-
- TActorIdentity TTaskActor::SelfId() noexcept {
- Y_ABORT_UNLESS(TlsCurrentTaskActor, "Not in a task actor context");
- return TlsCurrentTaskActor->SelfId();
- }
-
- TActorId TTaskActor::ParentId() noexcept {
- Y_ABORT_UNLESS(TlsCurrentTaskActor, "Not in a task actor context");
- return TlsCurrentTaskActor->ParentId;
- }
-
- void TAfterAwaiter::await_suspend(std::coroutine_handle<> h) noexcept {
- Y_ABORT_UNLESS(TlsCurrentTaskActor, "Not in a task actor context");
- TlsCurrentTaskActor->Schedule(Duration, new TEvResumeTask(h, &Result));
- }
-
- bool TBindAwaiter::await_ready() noexcept {
- if (TlsCurrentTaskActor && TlsCurrentTaskActor->SelfId() == ActorId) {
- return true;
- }
- return false;
- }
-
- void TBindAwaiter::await_suspend(std::coroutine_handle<> h) noexcept {
- Sys->Send(new IEventHandle(ActorId, ActorId, new TEvResumeTask(h, &Result)));
- }
-
-} // namespace NActors
diff --git a/library/cpp/actors/cppcoro/task_actor.h b/library/cpp/actors/cppcoro/task_actor.h
deleted file mode 100644
index 75d498a04e..0000000000
--- a/library/cpp/actors/cppcoro/task_actor.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#include <library/cpp/actors/core/actor.h>
-#include "task.h"
-
-namespace NActors {
-
- struct TTaskActorNextEvent {
- static constexpr bool await_ready() noexcept { return false; }
-
- static void await_suspend(std::coroutine_handle<> h) noexcept;
-
- static std::unique_ptr<IEventHandle> await_resume();
- };
-
- class TAfterAwaiter {
- public:
- TAfterAwaiter(TDuration duration)
- : Duration(duration)
- {}
-
- static constexpr bool await_ready() noexcept { return false; }
-
- void await_suspend(std::coroutine_handle<> h) noexcept;
-
- void await_resume() {
- Result.Value();
- }
-
- private:
- TDuration Duration;
- TTaskResult<void> Result;
- };
-
- class TBindAwaiter {
- public:
- TBindAwaiter(TActorSystem* sys, const TActorId& actorId)
- : Sys(sys)
- , ActorId(actorId)
- {}
-
- bool await_ready() noexcept;
-
- void await_suspend(std::coroutine_handle<> h) noexcept;
-
- void await_resume() {
- Result.Value();
- }
-
- private:
- TActorSystem* Sys;
- TActorId ActorId;
- TTaskResult<void> Result;
- };
-
- class TTaskActor {
- public:
- /**
- * Creates a new actor that will run the specified task.
- */
- static IActor* Create(TTask<void>&& task);
-
- /**
- * Returns the next actor event when awaited
- */
- static constexpr TTaskActorNextEvent NextEvent{};
-
- /**
- * Returns the identity of current task actor.
- */
- static TActorIdentity SelfId() noexcept;
-
- /**
- * Returns an actor id of the actor that registered current task actor.
- */
- static TActorId ParentId() noexcept;
-
- /**
- * Returns awaiter that completes after the specified timeout.
- */
- static TAfterAwaiter After(TDuration duration) noexcept {
- return TAfterAwaiter{ duration };
- }
-
- /**
- * Returns awaiter that completes on actor thread when awaited.
- */
- static TBindAwaiter Bind() noexcept {
- TActorId actorId = SelfId();
- TActorSystem* sys = TActivationContext::ActorSystem();
- return TBindAwaiter{ sys, actorId };
- }
-
- /**
- * Returns a task that runs the specified task, but binds the result
- * back to the actor thread. Useful when the specified task may be
- * working with non-actor coroutines.
- */
- template<class T>
- static TTask<T> Bind(TTask<T>&& task) {
- return [](TTask<T> task, TBindAwaiter bindTask) -> TTask<T> {
- auto result = co_await std::move(task).WhenDone();
- co_await bindTask;
- co_return std::move(result).Value();
- }(std::move(task), Bind());
- }
- };
-
-} // namespace NActors
diff --git a/library/cpp/actors/cppcoro/task_actor_ut.cpp b/library/cpp/actors/cppcoro/task_actor_ut.cpp
deleted file mode 100644
index 43186bfc55..0000000000
--- a/library/cpp/actors/cppcoro/task_actor_ut.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "task_actor.h"
-#include <library/cpp/actors/core/executor_pool_basic.h>
-#include <library/cpp/actors/core/scheduler_basic.h>
-
-#include <library/cpp/testing/unittest/registar.h>
-
-Y_UNIT_TEST_SUITE(TaskActor) {
-
- using namespace NActors;
-
- enum : ui32 {
- EvBegin = EventSpaceBegin(TEvents::ES_USERSPACE),
- EvRequest,
- EvResponse,
- EvStop,
- };
-
- struct TEvRequest: public TEventLocal<TEvRequest, EvRequest> {
- };
-
- struct TEvResponse: public TEventLocal<TEvResponse, EvResponse> {
- };
-
- struct TEvStop: public TEventLocal<TEvStop, EvStop> {
- };
-
- TTask<void> SimpleResponder() {
- for (;;) {
- auto ev = co_await TTaskActor::NextEvent;
- Y_ABORT_UNLESS(ev->GetTypeRewrite() == TEvRequest::EventType);
- auto* msg = ev->Get<TEvRequest>();
- Y_UNUSED(msg);
- TTaskActor::SelfId().Send(ev->Sender, new TEvResponse);
- }
- }
-
- TTask<void> SimpleRequester(TActorId responder, TManualEvent& doneEvent, std::atomic<int>& itemsProcessed) {
- // Note: it's ok to use lambda capture because captures outlive this coroutine
- auto singleRequest = [&]() -> TTask<bool> {
- TTaskActor::SelfId().Send(responder, new TEvRequest);
- auto ev = co_await TTaskActor::NextEvent;
- switch (ev->GetTypeRewrite()) {
- case TEvResponse::EventType:
- co_return true;
- case TEvStop::EventType:
- co_return false;
- default:
- Y_ABORT("Unexpected event");
- }
- };
- while (co_await singleRequest()) {
- ++itemsProcessed;
- }
- doneEvent.Signal();
- }
-
- void Check(TDuration duration, std::unique_ptr<IEventBase> stopEvent) {
- THolder<TActorSystemSetup> setup = MakeHolder<TActorSystemSetup>();
- 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;
- std::atomic<int> itemsProcessed{0};
-
- auto responder = actorSystem.Register(TTaskActor::Create(SimpleResponder()));
- auto requester = actorSystem.Register(TTaskActor::Create(SimpleRequester(responder, doneEvent, itemsProcessed)));
- auto deadline = TMonotonic::Now() + duration;
- while (itemsProcessed.load() < 10) {
- UNIT_ASSERT_C(TMonotonic::Now() < deadline, "cannot observe 10 responses in " << duration);
- Sleep(TDuration::MilliSeconds(100));
- }
- actorSystem.Send(requester, stopEvent.release());
- doneEvent.WaitI();
-
- UNIT_ASSERT_GE(itemsProcessed.load(), 10);
-
- actorSystem.Stop();
- }
-
- Y_UNIT_TEST(Basic) {
- Check(TDuration::Seconds(10), std::make_unique<TEvStop>());
- }
-
-} // Y_UNIT_TEST_SUITE(TaskActor)
diff --git a/library/cpp/actors/cppcoro/task_group.cpp b/library/cpp/actors/cppcoro/task_group.cpp
deleted file mode 100644
index 9ddd30d707..0000000000
--- a/library/cpp/actors/cppcoro/task_group.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "task_group.h"
diff --git a/library/cpp/actors/cppcoro/task_group.h b/library/cpp/actors/cppcoro/task_group.h
deleted file mode 100644
index 1de0cf5c1e..0000000000
--- a/library/cpp/actors/cppcoro/task_group.h
+++ /dev/null
@@ -1,302 +0,0 @@
-#pragma once
-#include "task_result.h"
-#include <util/generic/ptr.h>
-#include <util/system/compiler.h>
-#include <util/system/yassert.h>
-#include <coroutine>
-#include <atomic>
-#include <memory>
-
-namespace NActors {
-
- namespace NDetail {
-
- template<class T>
- struct TTaskGroupResult final : public TTaskResult<T> {
- TTaskGroupResult* Next;
- };
-
- template<class T>
- struct TTaskGroupSink final
- : public TAtomicRefCount<TTaskGroupSink<T>>
- {
- std::atomic<void*> LastReady{ nullptr };
- TTaskGroupResult<T>* ReadyQueue = nullptr;
- std::coroutine_handle<> Continuation;
-
- static constexpr uintptr_t MarkerAwaiting = 1;
- static constexpr uintptr_t MarkerDetached = 2;
-
- ~TTaskGroupSink() noexcept {
- if (!IsDetached()) {
- Detach();
- }
- }
-
- std::coroutine_handle<> Push(std::unique_ptr<TTaskGroupResult<T>>&& result) noexcept {
- void* currentValue = LastReady.load(std::memory_order_acquire);
- for (;;) {
- if (currentValue == (void*)MarkerAwaiting) {
- if (Y_UNLIKELY(!LastReady.compare_exchange_weak(currentValue, nullptr, std::memory_order_acquire))) {
- continue;
- }
- // We consume the awaiter
- Y_DEBUG_ABORT_UNLESS(ReadyQueue == nullptr, "TaskGroup is awaiting with non-empty ready queue");
- result->Next = ReadyQueue;
- ReadyQueue = result.release();
- return std::exchange(Continuation, {});
- }
- if (currentValue == (void*)MarkerDetached) {
- // Task group is detached, discard the result
- return std::noop_coroutine();
- }
- TTaskGroupResult<T>* current = reinterpret_cast<TTaskGroupResult<T>*>(currentValue);
- result->Next = current;
- void* nextValue = result.get();
- if (Y_LIKELY(LastReady.compare_exchange_weak(currentValue, nextValue, std::memory_order_acq_rel))) {
- // Result successfully added
- result.release();
- return std::noop_coroutine();
- }
- }
- }
-
- bool Ready() const noexcept {
- return ReadyQueue != nullptr || LastReady.load(std::memory_order_acquire) != nullptr;
- }
-
- Y_NO_INLINE std::coroutine_handle<> Suspend(std::coroutine_handle<> h) noexcept {
- Y_DEBUG_ABORT_UNLESS(ReadyQueue == nullptr, "Caller suspending with non-empty ready queue");
- Continuation = h;
- void* currentValue = LastReady.load(std::memory_order_acquire);
- for (;;) {
- if (currentValue == nullptr) {
- if (Y_UNLIKELY(!LastReady.compare_exchange_weak(currentValue, (void*)MarkerAwaiting, std::memory_order_release))) {
- continue;
- }
- // Continuation may wake up on another thread
- return std::noop_coroutine();
- }
- Y_ABORT_UNLESS(currentValue != (void*)MarkerAwaiting, "TaskGroup is suspending with an awaiting marker");
- Y_ABORT_UNLESS(currentValue != (void*)MarkerDetached, "TaskGroup is suspending with a detached marker");
- // Race: ready queue is not actually empty
- Continuation = {};
- return h;
- }
- }
-
- std::unique_ptr<TTaskGroupResult<T>> Resume() noexcept {
- std::unique_ptr<TTaskGroupResult<T>> result;
- if (ReadyQueue == nullptr) {
- void* headValue = LastReady.exchange(nullptr, std::memory_order_acq_rel);
- Y_ABORT_UNLESS(headValue != (void*)MarkerAwaiting, "TaskGroup is resuming with an awaiting marker");
- Y_ABORT_UNLESS(headValue != (void*)MarkerDetached, "TaskGroup is resuming with a detached marker");
- Y_ABORT_UNLESS(headValue, "TaskGroup is resuming with an empty queue");
- TTaskGroupResult<T>* head = reinterpret_cast<TTaskGroupResult<T>*>(headValue);
- while (head) {
- auto* next = std::exchange(head->Next, nullptr);
- head->Next = ReadyQueue;
- ReadyQueue = head;
- head = next;
- }
- }
- Y_ABORT_UNLESS(ReadyQueue != nullptr);
- result.reset(ReadyQueue);
- ReadyQueue = std::exchange(result->Next, nullptr);
- return result;
- }
-
- static void Dispose(TTaskGroupResult<T>* head) noexcept {
- while (head) {
- auto* next = std::exchange(head->Next, nullptr);
- std::unique_ptr<TTaskGroupResult<T>> ptr(head);
- head = next;
- }
- }
-
- bool IsDetached() const noexcept {
- void* headValue = LastReady.load(std::memory_order_acquire);
- return headValue == (void*)MarkerDetached;
- }
-
- void Detach() noexcept {
- // After this exchange all new results will be discarded
- void* headValue = LastReady.exchange((void*)MarkerDetached, std::memory_order_acq_rel);
- Y_ABORT_UNLESS(headValue != (void*)MarkerAwaiting, "TaskGroup is detaching with an awaiting marker");
- Y_ABORT_UNLESS(headValue != (void*)MarkerDetached, "TaskGroup is detaching with a detached marker");
- if (headValue) {
- Dispose(reinterpret_cast<TTaskGroupResult<T>*>(headValue));
- }
- if (ReadyQueue) {
- Dispose(std::exchange(ReadyQueue, nullptr));
- }
- }
- };
-
- template<class T>
- class TTaskGroupResultHandler {
- public:
- void unhandled_exception() noexcept {
- Result->SetException(std::current_exception());
- }
-
- template<class TResult>
- void return_value(TResult&& result) {
- Result->SetValue(std::forward<TResult>(result));
- }
-
- protected:
- std::unique_ptr<TTaskGroupResult<T>> Result = std::make_unique<TTaskGroupResult<T>>();
- };
-
- template<>
- class TTaskGroupResultHandler<void> {
- public:
- void unhandled_exception() noexcept {
- Result->SetException(std::current_exception());
- }
-
- void return_void() noexcept {
- Result->SetValue();
- }
-
- protected:
- std::unique_ptr<TTaskGroupResult<void>> Result = std::make_unique<TTaskGroupResult<void>>();
- };
-
- template<class T>
- class TTaskGroupPromise final : public TTaskGroupResultHandler<T> {
- public:
- using THandle = std::coroutine_handle<TTaskGroupPromise<T>>;
-
- THandle get_return_object() noexcept {
- return THandle::from_promise(*this);
- }
-
- static auto initial_suspend() noexcept { return std::suspend_always{}; }
-
- struct TFinalSuspend {
- static bool await_ready() noexcept { return false; }
- static void await_resume() noexcept { Y_ABORT("unexpected coroutine resume"); }
-
- Y_NO_INLINE
- static std::coroutine_handle<> await_suspend(std::coroutine_handle<TTaskGroupPromise<T>> h) noexcept {
- auto& promise = h.promise();
- auto sink = std::move(promise.Sink);
- auto next = sink->Push(std::move(promise.Result));
- h.destroy();
- return next;
- }
- };
-
- static auto final_suspend() noexcept { return TFinalSuspend{}; }
-
- void SetSink(const TIntrusivePtr<TTaskGroupSink<T>>& sink) {
- Sink = sink;
- }
-
- private:
- TIntrusivePtr<TTaskGroupSink<T>> Sink;
- };
-
- template<class T>
- class TTaskGroupTask final {
- public:
- using THandle = std::coroutine_handle<TTaskGroupPromise<T>>;
- using promise_type = TTaskGroupPromise<T>;
- using value_type = T;
-
- public:
- TTaskGroupTask(THandle handle)
- : Handle(handle)
- {}
-
- void Start(const TIntrusivePtr<TTaskGroupSink<T>>& sink) {
- Handle.promise().SetSink(sink);
- Handle.resume();
- }
-
- private:
- THandle Handle;
- };
-
- template<class T, class TAwaitable>
- TTaskGroupTask<T> CreateTaskGroupTask(TAwaitable awaitable) {
- co_return co_await std::move(awaitable);
- }
-
- } // namespace NDetail
-
- /**
- * A task group allows starting multiple subtasks of the same result type
- * and awaiting them in a structured way. When task group is destroyed
- * all subtasks are detached in a thread-safe way.
- */
- template<class T>
- class TTaskGroup {
- public:
- TTaskGroup() = default;
-
- TTaskGroup(const TTaskGroup&) = delete;
- TTaskGroup(TTaskGroup&&) = delete;
- TTaskGroup& operator=(const TTaskGroup&) = delete;
- TTaskGroup& operator=(TTaskGroup&&) = delete;
-
- ~TTaskGroup() {
- Sink_->Detach();
- }
-
- /**
- * Add task to the group that will await the result of awaitable
- */
- template<class TAwaitable>
- void AddTask(TAwaitable&& awaitable) {
- auto task = NDetail::CreateTaskGroupTask<T>(std::forward<TAwaitable>(awaitable));
- task.Start(Sink_);
- ++TaskCount_;
- }
-
- /**
- * Returns the number of tasks left unawaited
- */
- size_t TaskCount() const {
- return TaskCount_;
- }
-
- class TAwaiter {
- public:
- explicit TAwaiter(TTaskGroup& taskGroup) noexcept
- : TaskGroup_(taskGroup)
- {}
-
- bool await_ready() const noexcept {
- Y_ABORT_UNLESS(TaskGroup_.TaskCount_ > 0, "Not enough tasks to await");
- --TaskGroup_.TaskCount_;
- return TaskGroup_.Sink_->Ready();
- }
-
- std::coroutine_handle<> await_suspend(std::coroutine_handle<> h) noexcept {
- return TaskGroup_.Sink_->Suspend(h);
- }
-
- T await_resume() {
- return std::move(*TaskGroup_.Sink_->Resume()).Value();
- }
-
- private:
- TTaskGroup& TaskGroup_;
- };
-
- /**
- * Await result of the next task in the task group
- */
- TAwaiter operator co_await() noexcept {
- return TAwaiter(*this);
- }
-
- private:
- TIntrusivePtr<NDetail::TTaskGroupSink<T>> Sink_ = MakeIntrusive<NDetail::TTaskGroupSink<T>>();
- size_t TaskCount_ = 0;
- };
-
-} // namespace NActors
diff --git a/library/cpp/actors/cppcoro/task_result.cpp b/library/cpp/actors/cppcoro/task_result.cpp
deleted file mode 100644
index bb1a1dc5ca..0000000000
--- a/library/cpp/actors/cppcoro/task_result.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "task_result.h"
diff --git a/library/cpp/actors/cppcoro/task_result.h b/library/cpp/actors/cppcoro/task_result.h
deleted file mode 100644
index da78c53b7a..0000000000
--- a/library/cpp/actors/cppcoro/task_result.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#pragma once
-#include <util/system/yassert.h>
-#include <exception>
-#include <variant>
-
-namespace NActors {
-
- namespace NDetail {
-
- struct TVoid {};
-
- template<class T>
- struct TReplaceVoid {
- using TType = T;
- };
-
- template<>
- struct TReplaceVoid<void> {
- using TType = TVoid;
- };
-
- template<class T>
- struct TLValue {
- using TType = T&;
- };
-
- template<>
- struct TLValue<void> {
- using TType = void;
- };
-
- template<class T>
- struct TRValue {
- using TType = T&&;
- };
-
- template<>
- struct TRValue<void> {
- using TType = void;
- };
-
- } // namespace NDetail
-
- /**
- * Wrapper for the task result
- */
- template<class T>
- class TTaskResult {
- public:
- void SetValue()
- requires (std::same_as<T, void>)
- {
- Result.template emplace<1>();
- }
-
- template<class TResult>
- void SetValue(TResult&& result)
- requires (!std::same_as<T, void>)
- {
- Result.template emplace<1>(std::forward<TResult>(result));
- }
-
- void SetException(std::exception_ptr&& e) noexcept {
- Result.template emplace<2>(std::move(e));
- }
-
- typename NDetail::TLValue<T>::TType Value() & {
- switch (Result.index()) {
- case 0: {
- Y_ABORT("Task result has no value");
- }
- case 1: {
- if constexpr (std::same_as<T, void>) {
- return;
- } else {
- return std::get<1>(Result);
- }
- }
- case 2: {
- std::exception_ptr& e = std::get<2>(Result);
- Y_DEBUG_ABORT_UNLESS(e, "Task exception missing");
- std::rethrow_exception(e);
- }
- }
- Y_ABORT("Task result has an invalid state");
- }
-
- typename NDetail::TRValue<T>::TType Value() && {
- switch (Result.index()) {
- case 0: {
- Y_ABORT("Task result has no value");
- }
- case 1: {
- if constexpr (std::same_as<T, void>) {
- return;
- } else {
- return std::get<1>(std::move(Result));
- }
- }
- case 2: {
- std::exception_ptr& e = std::get<2>(Result);
- Y_DEBUG_ABORT_UNLESS(e, "Task exception missing");
- std::rethrow_exception(std::move(e));
- }
- }
- Y_ABORT("Task result has an invalid state");
- }
-
- private:
- std::variant<std::monostate, typename NDetail::TReplaceVoid<T>::TType, std::exception_ptr> Result;
- };
-
-} // namespace NActors
diff --git a/library/cpp/actors/cppcoro/task_ut.cpp b/library/cpp/actors/cppcoro/task_ut.cpp
deleted file mode 100644
index a1ed5426fc..0000000000
--- a/library/cpp/actors/cppcoro/task_ut.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-#include "task.h"
-#include "task_group.h"
-#include "await_callback.h"
-#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NActors;
-
-Y_UNIT_TEST_SUITE(Task) {
-
- TTask<void> SimpleReturnVoid() {
- co_return;
- }
-
- TTask<int> SimpleReturn42() {
- co_return 42;
- }
-
- Y_UNIT_TEST(SimpleVoidCoroutine) {
- bool finished = false;
- AwaitThenCallback(SimpleReturnVoid(), [&]() {
- finished = true;
- });
- UNIT_ASSERT(finished);
- }
-
- Y_UNIT_TEST(SimpleIntCoroutine) {
- std::optional<int> result;
- AwaitThenCallback(SimpleReturn42(), [&](int value) {
- result = value;
- });
- UNIT_ASSERT(result);
- UNIT_ASSERT_VALUES_EQUAL(*result, 42);
- }
-
- Y_UNIT_TEST(SimpleVoidWhenDone) {
- std::optional<TTaskResult<void>> result;
- AwaitThenCallback(SimpleReturnVoid().WhenDone(), [&](auto value) {
- result = std::move(value);
- });
- UNIT_ASSERT(result);
- result->Value();
- }
-
- Y_UNIT_TEST(SimpleIntWhenDone) {
- std::optional<TTaskResult<int>> result;
- AwaitThenCallback(SimpleReturn42().WhenDone(), [&](auto value) {
- result = std::move(value);
- });
- UNIT_ASSERT(result);
- UNIT_ASSERT_VALUES_EQUAL(result->Value(), 42);
- }
-
- template<class TCallback>
- TTask<int> CallTwice(TCallback callback) {
- int a = co_await callback();
- int b = co_await callback();
- co_return a + b;
- }
-
- Y_UNIT_TEST(NestedAwait) {
- auto task = CallTwice([]{
- return SimpleReturn42();
- });
- UNIT_ASSERT(task);
- std::optional<int> result;
- AwaitThenCallback(std::move(task), [&](int value) {
- result = value;
- });
- UNIT_ASSERT(result);
- UNIT_ASSERT_VALUES_EQUAL(*result, 84);
- }
-
- template<class T>
- struct TPauseState {
- std::coroutine_handle<> Next;
- std::optional<T> NextResult;
-
- ~TPauseState() {
- while (Next) {
- NextResult.reset();
- std::exchange(Next, {}).resume();
- }
- }
-
- struct TAwaiter {
- TPauseState* State;
-
- bool await_ready() const noexcept { return false; }
- void await_suspend(std::coroutine_handle<> c) const noexcept {
- State->Next = c;
- }
- T await_resume() const {
- if (!State->NextResult) {
- throw TTaskCancelled();
- } else {
- T result = std::move(*State->NextResult);
- State->NextResult.reset();
- return result;
- }
- }
- };
-
- auto Wait() {
- return TAwaiter{ this };
- }
-
- explicit operator bool() const {
- return bool(Next);
- }
-
- void Resume(T result) {
- Y_ABORT_UNLESS(Next && !Next.done());
- NextResult = result;
- std::exchange(Next, {}).resume();
- }
-
- void Cancel() {
- Y_ABORT_UNLESS(Next && !Next.done());
- NextResult.reset();
- std::exchange(Next, {}).resume();
- }
- };
-
- Y_UNIT_TEST(PauseResume) {
- TPauseState<int> state;
- auto task = CallTwice([&]{
- return state.Wait();
- });
- std::optional<int> result;
- AwaitThenCallback(std::move(task), [&](int value) {
- result = value;
- });
- UNIT_ASSERT(!result);
- UNIT_ASSERT(state);
- state.Resume(11);
- UNIT_ASSERT(!result);
- UNIT_ASSERT(state);
- state.Resume(22);
- UNIT_ASSERT(result);
- UNIT_ASSERT_VALUES_EQUAL(*result, 33);
- }
-
- Y_UNIT_TEST(PauseCancel) {
- TPauseState<int> state;
- auto task = CallTwice([&]{
- return state.Wait();
- });
- std::optional<int> result;
- AwaitThenCallback(std::move(task).WhenDone(), [&](TTaskResult<int>&& value) {
- try {
- result = value.Value();
- } catch (TTaskCancelled&) {
- // nothing
- }
- });
- UNIT_ASSERT(!result);
- UNIT_ASSERT(state);
- state.Resume(11);
- UNIT_ASSERT(!result);
- UNIT_ASSERT(state);
- state.Cancel();
- UNIT_ASSERT(!result);
- }
-
- Y_UNIT_TEST(GroupWithTwoSubTasks) {
- TPauseState<int> state1;
- TPauseState<int> state2;
-
- std::vector<int> results;
- auto task = [](auto& state1, auto& state2, auto& results) -> TTask<int> {
- TTaskGroup<int> group;
- group.AddTask(state1.Wait());
- group.AddTask(state2.Wait());
- int a = co_await group;
- results.push_back(a);
- int b = co_await group;
- results.push_back(b);
- co_return a + b;
- }(state1, state2, results);
-
- std::optional<int> result;
- AwaitThenCallback(std::move(task), [&](int value) {
- result = value;
- });
-
- // We must be waiting for both states
- UNIT_ASSERT(state1);
- UNIT_ASSERT(state2);
- state2.Resume(22);
- UNIT_ASSERT_VALUES_EQUAL(results.size(), 1u);
- UNIT_ASSERT_VALUES_EQUAL(results.at(0), 22);
- UNIT_ASSERT(!result);
- state1.Resume(11);
- UNIT_ASSERT_VALUES_EQUAL(results.size(), 2u);
- UNIT_ASSERT_VALUES_EQUAL(results.at(1), 11);
- UNIT_ASSERT(result);
- UNIT_ASSERT_VALUES_EQUAL(*result, 33);
- }
-
- Y_UNIT_TEST(GroupWithTwoSubTasksDetached) {
- TPauseState<int> state1;
- TPauseState<int> state2;
-
- std::vector<int> results;
- auto task = [](auto& state1, auto& state2, auto& results) -> TTask<int> {
- TTaskGroup<int> group;
- group.AddTask(state1.Wait());
- group.AddTask(state2.Wait());
- int a = co_await group;
- results.push_back(a);
- co_return a;
- }(state1, state2, results);
-
- std::optional<int> result;
- AwaitThenCallback(std::move(task), [&](int value) {
- result = value;
- });
-
- // We must be waiting for both states
- UNIT_ASSERT(state1);
- UNIT_ASSERT(state2);
- state2.Resume(22);
- UNIT_ASSERT_VALUES_EQUAL(results.size(), 1u);
- UNIT_ASSERT_VALUES_EQUAL(results.at(0), 22);
- UNIT_ASSERT(result);
- UNIT_ASSERT_VALUES_EQUAL(*result, 22);
- }
-
- Y_UNIT_TEST(GroupWithTwoSubTasksOneCancelled) {
- TPauseState<int> state1;
- TPauseState<int> state2;
- std::vector<int> results;
- auto task = [](auto& state1, auto& state2, auto& results) -> TTask<void> {
- TTaskGroup<int> group;
- group.AddTask(state1.Wait());
- group.AddTask(state2.Wait());
- for (int i = 0; i < 2; ++i) {
- try {
- results.push_back(co_await group);
- } catch (TTaskCancelled&) {
- results.push_back(-1);
- }
- }
- }(state1, state2, results);
-
- bool finished = false;
- AwaitThenCallback(std::move(task), [&]() {
- finished = true;
- });
-
- UNIT_ASSERT(state1);
- UNIT_ASSERT(state2);
- state2.Cancel();
- UNIT_ASSERT_VALUES_EQUAL(results.size(), 1u);
- UNIT_ASSERT_VALUES_EQUAL(results.at(0), -1);
- UNIT_ASSERT(!finished);
- state1.Resume(11);
- UNIT_ASSERT_VALUES_EQUAL(results.size(), 2u);
- UNIT_ASSERT_VALUES_EQUAL(results.at(1), 11);
- UNIT_ASSERT(finished);
- }
-
-} // Y_UNIT_TEST_SUITE(Task)
diff --git a/library/cpp/actors/cppcoro/ut/CMakeLists.darwin-arm64.txt b/library/cpp/actors/cppcoro/ut/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 5ec40dbae9..0000000000
--- a/library/cpp/actors/cppcoro/ut/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-cppcoro-ut)
-target_include_directories(library-cpp-actors-cppcoro-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro
-)
-target_link_libraries(library-cpp-actors-cppcoro-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-cppcoro
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-cppcoro-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-cppcoro-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-cppcoro-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-cppcoro-ut
- TEST_TARGET
- library-cpp-actors-cppcoro-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-cppcoro-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-cppcoro-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-cppcoro-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-cppcoro-ut)
diff --git a/library/cpp/actors/cppcoro/ut/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/cppcoro/ut/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 7cebff01de..0000000000
--- a/library/cpp/actors/cppcoro/ut/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-cppcoro-ut)
-target_include_directories(library-cpp-actors-cppcoro-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro
-)
-target_link_libraries(library-cpp-actors-cppcoro-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-cppcoro
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-cppcoro-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-cppcoro-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-cppcoro-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-cppcoro-ut
- TEST_TARGET
- library-cpp-actors-cppcoro-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-cppcoro-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-cppcoro-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-cppcoro-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-cppcoro-ut)
diff --git a/library/cpp/actors/cppcoro/ut/CMakeLists.linux-aarch64.txt b/library/cpp/actors/cppcoro/ut/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 4a11af3456..0000000000
--- a/library/cpp/actors/cppcoro/ut/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-cppcoro-ut)
-target_include_directories(library-cpp-actors-cppcoro-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro
-)
-target_link_libraries(library-cpp-actors-cppcoro-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-cppcoro
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-cppcoro-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-cppcoro-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-cppcoro-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-cppcoro-ut
- TEST_TARGET
- library-cpp-actors-cppcoro-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-cppcoro-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-cppcoro-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-cppcoro-ut
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-cppcoro-ut)
diff --git a/library/cpp/actors/cppcoro/ut/CMakeLists.linux-x86_64.txt b/library/cpp/actors/cppcoro/ut/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 2e2412f989..0000000000
--- a/library/cpp/actors/cppcoro/ut/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-cppcoro-ut)
-target_include_directories(library-cpp-actors-cppcoro-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro
-)
-target_link_libraries(library-cpp-actors-cppcoro-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-cppcoro
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-cppcoro-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-cppcoro-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-cppcoro-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-cppcoro-ut
- TEST_TARGET
- library-cpp-actors-cppcoro-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-cppcoro-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-cppcoro-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-cppcoro-ut
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-cppcoro-ut)
diff --git a/library/cpp/actors/cppcoro/ut/CMakeLists.txt b/library/cpp/actors/cppcoro/ut/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/cppcoro/ut/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/cppcoro/ut/CMakeLists.windows-x86_64.txt b/library/cpp/actors/cppcoro/ut/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index e3b8b019c8..0000000000
--- a/library/cpp/actors/cppcoro/ut/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-cppcoro-ut)
-target_include_directories(library-cpp-actors-cppcoro-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro
-)
-target_link_libraries(library-cpp-actors-cppcoro-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-cppcoro
- cpp-actors-testlib
-)
-target_sources(library-cpp-actors-cppcoro-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/cppcoro/task_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-cppcoro-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-cppcoro-ut
- TEST_TARGET
- library-cpp-actors-cppcoro-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-cppcoro-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-cppcoro-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-cppcoro-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-cppcoro-ut)
diff --git a/library/cpp/actors/cppcoro/ut/ya.make b/library/cpp/actors/cppcoro/ut/ya.make
deleted file mode 100644
index 24a9c73613..0000000000
--- a/library/cpp/actors/cppcoro/ut/ya.make
+++ /dev/null
@@ -1,12 +0,0 @@
-UNITTEST_FOR(library/cpp/actors/cppcoro)
-
-PEERDIR(
- library/cpp/actors/testlib
-)
-
-SRCS(
- task_ut.cpp
- task_actor_ut.cpp
-)
-
-END()
diff --git a/library/cpp/actors/cppcoro/ya.make b/library/cpp/actors/cppcoro/ya.make
deleted file mode 100644
index 4df4f05302..0000000000
--- a/library/cpp/actors/cppcoro/ya.make
+++ /dev/null
@@ -1,25 +0,0 @@
-LIBRARY()
-
-PEERDIR(
- library/cpp/actors/core
-)
-
-SRCS(
- await_callback.cpp
- await_callback.h
- task_actor.cpp
- task_actor.h
- task_group.cpp
- task_group.h
- task_result.cpp
- task_result.h
- task.cpp
- task.h
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- corobenchmark
- ut
-)
diff --git a/library/cpp/actors/dnscachelib/CMakeLists.darwin-arm64.txt b/library/cpp/actors/dnscachelib/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index b769b26408..0000000000
--- a/library/cpp/actors/dnscachelib/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-dnscachelib)
-target_link_libraries(cpp-actors-dnscachelib PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-c-ares
- library-cpp-lwtrace
- cpp-deprecated-atomic
-)
-target_sources(cpp-actors-dnscachelib PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnscachelib/dnscache.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnscachelib/probes.cpp
-)
diff --git a/library/cpp/actors/dnscachelib/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/dnscachelib/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index b769b26408..0000000000
--- a/library/cpp/actors/dnscachelib/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-dnscachelib)
-target_link_libraries(cpp-actors-dnscachelib PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-c-ares
- library-cpp-lwtrace
- cpp-deprecated-atomic
-)
-target_sources(cpp-actors-dnscachelib PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnscachelib/dnscache.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnscachelib/probes.cpp
-)
diff --git a/library/cpp/actors/dnscachelib/CMakeLists.linux-aarch64.txt b/library/cpp/actors/dnscachelib/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 60de9ca5ab..0000000000
--- a/library/cpp/actors/dnscachelib/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-dnscachelib)
-target_link_libraries(cpp-actors-dnscachelib PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-c-ares
- library-cpp-lwtrace
- cpp-deprecated-atomic
-)
-target_sources(cpp-actors-dnscachelib PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnscachelib/dnscache.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnscachelib/probes.cpp
-)
diff --git a/library/cpp/actors/dnscachelib/CMakeLists.linux-x86_64.txt b/library/cpp/actors/dnscachelib/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 60de9ca5ab..0000000000
--- a/library/cpp/actors/dnscachelib/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-dnscachelib)
-target_link_libraries(cpp-actors-dnscachelib PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-c-ares
- library-cpp-lwtrace
- cpp-deprecated-atomic
-)
-target_sources(cpp-actors-dnscachelib PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnscachelib/dnscache.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnscachelib/probes.cpp
-)
diff --git a/library/cpp/actors/dnscachelib/CMakeLists.txt b/library/cpp/actors/dnscachelib/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/dnscachelib/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/dnscachelib/CMakeLists.windows-x86_64.txt b/library/cpp/actors/dnscachelib/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index b769b26408..0000000000
--- a/library/cpp/actors/dnscachelib/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-dnscachelib)
-target_link_libraries(cpp-actors-dnscachelib PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-c-ares
- library-cpp-lwtrace
- cpp-deprecated-atomic
-)
-target_sources(cpp-actors-dnscachelib PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnscachelib/dnscache.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnscachelib/probes.cpp
-)
diff --git a/library/cpp/actors/dnscachelib/dnscache.cpp b/library/cpp/actors/dnscachelib/dnscache.cpp
deleted file mode 100644
index 91ed284c12..0000000000
--- a/library/cpp/actors/dnscachelib/dnscache.cpp
+++ /dev/null
@@ -1,458 +0,0 @@
-#include "dnscache.h"
-#include "probes.h"
-#include "timekeeper.h"
-
-#include <ares.h>
-#include <util/system/guard.h>
-#include <util/datetime/systime.h>
-
-const TDnsCache::THost TDnsCache::NullHost;
-
-LWTRACE_USING(DNSCACHELIB_PROVIDER);
-
-static_assert(sizeof(ares_channel) == sizeof(void*), "expect sizeof(ares_channel) == sizeof(void *)");
-
-TDnsCache::TDnsCache(bool allowIpv4, bool allowIpv6, time_t lifetime, time_t neg, ui32 timeout)
- : EntryLifetime(lifetime)
- , NegativeLifetime(neg)
- , Timeout(TDuration::MicroSeconds(timeout))
- , AllowIpV4(allowIpv4)
- , AllowIpV6(allowIpv6)
- , ACacheHits(0)
- , ACacheMisses(0)
- , PtrCacheHits(0)
- , PtrCacheMisses(0)
-{
-#ifdef _win_
- if (ares_library_init(ARES_LIB_INIT_WIN32) != ARES_SUCCESS) {
- LWPROBE(AresInitFailed);
- ythrow yexception() << "ares_init() failed";
- }
-#endif
-
- ares_channel chan;
-
- if (ares_init(&chan) != ARES_SUCCESS) {
- LWPROBE(AresInitFailed);
- ythrow yexception() << "ares_init() failed";
- }
- Channel = chan;
- LWPROBE(Created);
-}
-
-TDnsCache::~TDnsCache(void) {
- ares_channel chan = static_cast<ares_channel>(Channel);
-
- ares_cancel(chan);
- ares_destroy(chan);
- LWPROBE(Destroyed);
-
-#ifdef _win_
- ares_library_cleanup();
-#endif
-}
-
-TString TDnsCache::GetHostByAddr(const NAddr::IRemoteAddr& addr) {
- in6_addr key;
-
- if (addr.Addr()->sa_family == AF_INET6) {
- const struct sockaddr_in6* s6 = (const struct sockaddr_in6*)(addr.Addr());
- memcpy(&key, &s6->sin6_addr, sizeof(s6->sin6_addr));
- } else if (addr.Addr()->sa_family == AF_INET) {
- const struct sockaddr_in* s4 = (const struct sockaddr_in*)(addr.Addr());
- memset(&key, 0, sizeof(key));
- memcpy(&key, &s4->sin_addr, sizeof(s4->sin_addr));
- } else {
- return "";
- }
- const TAddr& host = ResolveAddr(key, addr.Addr()->sa_family);
-
- return host.Hostname;
-}
-
-TIpHost TDnsCache::Get(const TString& hostname) {
- if (!AllowIpV4)
- return TIpHost(-1);
-
- const THost& addr = Resolve(hostname, AF_INET);
-
- TGuard<TMutex> lock(CacheMtx);
- if (addr.AddrsV4.empty()) {
- return TIpHost(-1);
- }
- return addr.AddrsV4.front();
-}
-
-NAddr::IRemoteAddrPtr TDnsCache::GetAddr(
- const TString& hostname,
- int family,
- TIpPort port,
- bool cacheOnly) {
- if (family != AF_INET && AllowIpV6) {
- const THost& addr = Resolve(hostname, AF_INET6, cacheOnly);
-
- TGuard<TMutex> lock(CacheMtx);
- if (!addr.AddrsV6.empty()) {
- struct sockaddr_in6 sin6;
- Zero(sin6);
- sin6.sin6_family = AF_INET6;
- sin6.sin6_addr = addr.AddrsV6.front();
- sin6.sin6_port = HostToInet(port);
-
- return MakeHolder<NAddr::TIPv6Addr>(sin6);
- }
- }
-
- if (family != AF_INET6 && AllowIpV4) {
- const THost& addr = Resolve(hostname, AF_INET, cacheOnly);
-
- TGuard<TMutex> lock(CacheMtx);
- if (!addr.AddrsV4.empty()) {
- return MakeHolder<NAddr::TIPv4Addr>(TIpAddress(addr.AddrsV4.front(), port));
- }
- }
-
- LWPROBE(FamilyMismatch, family, AllowIpV4, AllowIpV6);
- return nullptr;
-}
-
-void TDnsCache::GetAllAddresses(
- const TString& hostname,
- TVector<NAddr::IRemoteAddrPtr>& addrs) {
- if (AllowIpV4) {
- const THost& addr4 = Resolve(hostname, AF_INET);
-
- TGuard<TMutex> lock(CacheMtx);
- for (size_t i = 0; i < addr4.AddrsV4.size(); i++) {
- addrs.push_back(MakeHolder<NAddr::TIPv4Addr>(TIpAddress(addr4.AddrsV4[i], 0)));
- }
- }
-
- if (AllowIpV6) {
- const THost& addr6 = Resolve(hostname, AF_INET6);
-
- struct sockaddr_in6 sin6;
- Zero(sin6);
- sin6.sin6_family = AF_INET6;
-
- TGuard<TMutex> lock(CacheMtx);
- for (size_t i = 0; i < addr6.AddrsV6.size(); i++) {
- sin6.sin6_addr = addr6.AddrsV6[i];
-
- addrs.push_back(MakeHolder<NAddr::TIPv6Addr>(sin6));
- }
- }
-}
-
-void TDnsCache::GetStats(ui64& a_cache_hits, ui64& a_cache_misses,
- ui64& ptr_cache_hits, ui64& ptr_cache_misses) {
- TGuard<TMutex> lock(CacheMtx);
-
- a_cache_hits = ACacheHits;
- a_cache_misses = ACacheMisses;
- ptr_cache_hits = PtrCacheHits;
- ptr_cache_misses = PtrCacheMisses;
-}
-
-bool TDnsCache::THost::IsStale(int family, const TDnsCache* ctx) const noexcept {
- time_t resolved = family == AF_INET ? ResolvedV4 : ResolvedV6;
- time_t notfound = family == AF_INET ? NotFoundV4 : NotFoundV6;
-
- if (TTimeKeeper::GetTime() - resolved < ctx->EntryLifetime)
- return false;
-
- if (TTimeKeeper::GetTime() - notfound < ctx->NegativeLifetime)
- return false;
-
- return true;
-}
-
-const TDnsCache::THost&
-TDnsCache::Resolve(const TString& hostname, int family, bool cacheOnly) {
- if (!ValidateHName(hostname)) {
- LWPROBE(ResolveNullHost, hostname, family);
- return NullHost;
- }
-
- THostCache::iterator p;
-
- Y_ASSERT(family == AF_INET || family == AF_INET6);
-
- {
- TGuard<TMutex> lock(CacheMtx);
- p = HostCache.find(hostname);
- if (p != HostCache.end()) {
- if (!p->second.IsStale(family, this)) {
- /* Recently resolved, just return cached value */
- ACacheHits += 1;
- THost& host = p->second;
- LWPROBE(ResolveFromCache, hostname, family, host.AddrsV4ToString(), host.AddrsV6ToString(), ACacheHits);
- return host;
- } else {
- LWPROBE(ResolveCacheTimeout, hostname);
- }
- } else {
- /* Never resolved, create cache entry */
- LWPROBE(ResolveCacheNew, hostname);
- p = HostCache.insert(std::make_pair(hostname, THost())).first;
- }
- ACacheMisses += 1;
- }
-
- if (cacheOnly)
- return NullHost;
-
- TAtomic& inprogress = (family == AF_INET ? p->second.InProgressV4 : p->second.InProgressV6);
-
- {
- /* This way only! CacheMtx should always be taken AFTER AresMtx,
- * because later in ares_process it can only be done this way.
- * Lock order reversal will cause deadlock in unfortunate monents.
- */
- TGuard<TMutex> areslock(AresMtx);
- TGuard<TMutex> cachelock(CacheMtx);
-
- if (!inprogress) {
- ares_channel chan = static_cast<ares_channel>(Channel);
- TGHBNContext* ctx = new TGHBNContext();
- ctx->Owner = this;
- ctx->Hostname = hostname;
- ctx->Family = family;
-
- AtomicSet(inprogress, 1);
- ares_gethostbyname(chan, hostname.c_str(), family,
- &TDnsCache::GHBNCallback, ctx);
- }
- }
-
- WaitTask(inprogress);
-
- LWPROBE(ResolveDone, hostname, family, p->second.AddrsV4ToString(), p->second.AddrsV6ToString());
- return p->second;
-}
-
-bool TDnsCache::ValidateHName(const TString& name) const noexcept {
- return name.size() > 0;
-}
-
-const TDnsCache::TAddr& TDnsCache::ResolveAddr(const in6_addr& addr, int family) {
- TAddrCache::iterator p;
-
- {
- TGuard<TMutex> lock(CacheMtx);
- p = AddrCache.find(addr);
- if (p != AddrCache.end()) {
- if (TTimeKeeper::GetTime() - p->second.Resolved < EntryLifetime || TTimeKeeper::GetTime() - p->second.NotFound < NegativeLifetime) {
- /* Recently resolved, just return cached value */
- PtrCacheHits += 1;
- return p->second;
- }
- } else {
- /* Never resolved, create cache entry */
-
- p = AddrCache.insert(std::make_pair(addr, TAddr())).first;
- }
- PtrCacheMisses += 1;
- }
-
- {
- /* This way only! CacheMtx should always be taken AFTER AresMtx,
- * because later in ares_process it can only be done this way.
- * Lock order reversal will cause deadlock in unfortunate monents.
- */
- TGuard<TMutex> areslock(AresMtx);
- TGuard<TMutex> cachelock(CacheMtx);
-
- if (!p->second.InProgress) {
- ares_channel chan = static_cast<ares_channel>(Channel);
- TGHBAContext* ctx = new TGHBAContext();
- ctx->Owner = this;
- ctx->Addr = addr;
-
- AtomicSet(p->second.InProgress, 1);
- ares_gethostbyaddr(chan, &addr,
- family == AF_INET ? sizeof(in_addr) : sizeof(in6_addr),
- family, &TDnsCache::GHBACallback, ctx);
- }
- }
-
- WaitTask(p->second.InProgress);
-
- return p->second;
-}
-
-void TDnsCache::WaitTask(TAtomic& flag) {
- const TInstant start = TInstant(TTimeKeeper::GetTimeval());
-
- while (AtomicGet(flag)) {
- ares_channel chan = static_cast<ares_channel>(Channel);
-
- struct pollfd pfd[ARES_GETSOCK_MAXNUM];
- int nfds;
- ares_socket_t socks[ARES_GETSOCK_MAXNUM];
- int bits;
-
- {
- TGuard<TMutex> lock(AresMtx);
- bits = ares_getsock(chan, socks, ARES_GETSOCK_MAXNUM);
- if (bits == 0) {
- /* other thread did our job */
- continue;
- }
- }
-
- for (nfds = 0; nfds < ARES_GETSOCK_MAXNUM; nfds++) {
- pfd[nfds].events = 0;
- pfd[nfds].revents = 0;
- if (ARES_GETSOCK_READABLE(bits, nfds)) {
- pfd[nfds].fd = socks[nfds];
- pfd[nfds].events |= POLLRDNORM | POLLIN;
- }
- if (ARES_GETSOCK_WRITABLE(bits, nfds)) {
- pfd[nfds].fd = socks[nfds];
- pfd[nfds].events |= POLLWRNORM | POLLOUT;
- }
- if (pfd[nfds].events == 0) {
- break;
- }
- }
-
- Y_ASSERT(nfds != 0);
-
- const TDuration left = TInstant(TTimeKeeper::GetTimeval()) - start;
- const TDuration wait = Max(Timeout - left, TDuration::Zero());
-
- int rv = poll(pfd, nfds, wait.MilliSeconds());
-
- if (rv == -1) {
- if (errno == EINTR) {
- continue;
- }
- /* Unknown error in select, can't recover. Just pretend there was no reply */
- rv = 0;
- }
-
- if (rv == 0) {
- /* poll() timed out */
- TGuard<TMutex> lock(AresMtx);
- ares_process_fd(chan, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
- } else {
- for (int i = 0; i < nfds; i++) {
- if (pfd[i].revents == 0) {
- continue;
- }
- TGuard<TMutex> lock(AresMtx);
- ares_process_fd(chan,
- pfd[i].revents & (POLLRDNORM | POLLIN)
- ? pfd[i].fd
- : ARES_SOCKET_BAD,
- pfd[i].revents & (POLLWRNORM | POLLOUT)
- ? pfd[i].fd
- : ARES_SOCKET_BAD);
- }
- }
-
- if (start + Timeout <= TInstant(TTimeKeeper::GetTimeval())) {
- break;
- }
- }
-}
-
-void TDnsCache::GHBNCallback(void* arg, int status, int, struct hostent* info) {
- THolder<TGHBNContext> ctx(static_cast<TGHBNContext*>(arg));
- TGuard<TMutex> lock(ctx->Owner->CacheMtx);
- THostCache::iterator p = ctx->Owner->HostCache.find(ctx->Hostname);
-
- Y_ASSERT(p != ctx->Owner->HostCache.end());
-
- time_t& resolved = (ctx->Family == AF_INET ? p->second.ResolvedV4 : p->second.ResolvedV6);
- time_t& notfound = (ctx->Family == AF_INET ? p->second.NotFoundV4 : p->second.NotFoundV6);
- TAtomic& inprogress = (ctx->Family == AF_INET ? p->second.InProgressV4 : p->second.InProgressV6);
-
- if (status == ARES_SUCCESS) {
- if (info->h_addrtype == AF_INET) {
- p->second.AddrsV4.clear();
- for (int i = 0; info->h_addr_list[i] != nullptr; i++) {
- p->second.AddrsV4.push_back(*(TIpHost*)(info->h_addr_list[i]));
- }
- /* It is possible to ask ares for IPv6 and have IPv4 addrs instead,
- so take care and set V4 timers anyway.
- */
- p->second.ResolvedV4 = TTimeKeeper::GetTime();
- p->second.ResolvedV4 = 0;
- AtomicSet(p->second.InProgressV4, 0);
- } else if (info->h_addrtype == AF_INET6) {
- p->second.AddrsV6.clear();
- for (int i = 0; info->h_addr_list[i] != nullptr; i++) {
- p->second.AddrsV6.push_back(*(struct in6_addr*)(info->h_addr_list[i]));
- }
- } else {
- Y_ABORT("unknown address type in ares callback");
- }
- resolved = TTimeKeeper::GetTime();
- notfound = 0;
- } else {
- notfound = TTimeKeeper::GetTime();
- resolved = 0;
- }
- AtomicSet(inprogress, 0);
-}
-
-void TDnsCache::GHBACallback(void* arg, int status, int, struct hostent* info) {
- THolder<TGHBAContext> ctx(static_cast<TGHBAContext*>(arg));
- TGuard<TMutex> lock(ctx->Owner->CacheMtx);
- TAddrCache::iterator p = ctx->Owner->AddrCache.find(ctx->Addr);
-
- Y_ASSERT(p != ctx->Owner->AddrCache.end());
-
- if (status == ARES_SUCCESS) {
- p->second.Hostname = info->h_name;
- p->second.Resolved = TTimeKeeper::GetTime();
- p->second.NotFound = 0;
- } else {
- p->second.NotFound = TTimeKeeper::GetTime();
- p->second.Resolved = 0;
- }
- AtomicSet(p->second.InProgress, 0);
-}
-
-TString TDnsCache::THost::AddrsV4ToString() const {
- TStringStream ss;
- bool first = false;
- for (TIpHost addr : AddrsV4) {
- ss << (first ? "" : " ") << IpToString(addr);
- first = false;
- }
- return ss.Str();
-}
-
-TString TDnsCache::THost::AddrsV6ToString() const {
- TStringStream ss;
- bool first = false;
- for (in6_addr addr : AddrsV6) {
- struct sockaddr_in6 sin6;
- Zero(sin6);
- sin6.sin6_family = AF_INET6;
- sin6.sin6_addr = addr;
-
- NAddr::TIPv6Addr addr6(sin6);
- ss << (first ? "" : " ") << NAddr::PrintHost(addr6);
- first = false;
- }
- return ss.Str();
-}
-
-TDnsCache::TAresLibInit::TAresLibInit() {
-#ifdef _win_
- const auto res = ares_library_init(ARES_LIB_INIT_ALL);
- Y_ABORT_UNLESS(res == 0);
-#endif
-}
-
-TDnsCache::TAresLibInit::~TAresLibInit() {
-#ifdef _win_
- ares_library_cleanup();
-#endif
-}
-
-TDnsCache::TAresLibInit TDnsCache::InitAresLib;
diff --git a/library/cpp/actors/dnscachelib/dnscache.h b/library/cpp/actors/dnscachelib/dnscache.h
deleted file mode 100644
index ac36e6ddc0..0000000000
--- a/library/cpp/actors/dnscachelib/dnscache.h
+++ /dev/null
@@ -1,139 +0,0 @@
-#pragma once
-
-#include <library/cpp/deprecated/atomic/atomic.h>
-
-#include <util/generic/map.h>
-#include <util/generic/vector.h>
-#include <util/network/address.h>
-#include <util/system/mutex.h>
-#include <util/datetime/base.h>
-
-/** Asynchronous DNS resolver.
- *
- * This is NOT general purpose resolver! It is designed with very specific assumptions:
- * 1) there is relatively small and rarely changed set of resolved names (like, server pool in cluster)
- * 2) this names supposed to have addresses, absense of A record is equal to DNS error
- * 3) most of the time IP addresses do not change
- * 4) it's OK to return old IP address when DNS server not responding in time
- */
-
-class TDnsCache {
-public:
- TDnsCache(bool allowIpv4 = true, bool allowIpv6 = true, time_t entry_lifetime = 1800, time_t neg_lifetime = 1, ui32 request_timeout = 500000);
- ~TDnsCache();
-
- TString GetHostByAddr(const NAddr::IRemoteAddr&);
-
- // ip in network byte order
- TIpHost Get(const TString& host);
-
- /* use with AF_INET, AF_INET6 or AF_UNSPEC */
- NAddr::IRemoteAddrPtr GetAddr(const TString& host,
- int family,
- TIpPort port = 0,
- bool cacheOnly = false);
-
- void GetAllAddresses(const TString& host, TVector<NAddr::IRemoteAddrPtr>&);
-
- void GetStats(ui64& a_cache_hits, ui64& a_cache_misses,
- ui64& ptr_cache_hits, ui64& ptr_cache_misses);
-
-protected:
- bool ValidateHName(const TString& host) const noexcept;
-
-private:
- struct TGHBNContext {
- TDnsCache* Owner;
- TString Hostname;
- int Family;
- };
-
- struct TGHBAContext {
- TDnsCache* Owner;
- in6_addr Addr;
- };
-
- struct THost {
- THost() noexcept {
- }
-
- TVector<TIpHost> AddrsV4;
- time_t ResolvedV4 = 0;
- time_t NotFoundV4 = 0;
- TAtomic InProgressV4 = 0;
-
- TVector<in6_addr> AddrsV6;
- time_t ResolvedV6 = 0;
- time_t NotFoundV6 = 0;
- TAtomic InProgressV6 = 0;
-
- TString AddrsV4ToString() const;
- TString AddrsV6ToString() const;
-
- bool IsStale(int family, const TDnsCache* ctx) const noexcept;
- };
-
- typedef TMap<TString, THost> THostCache;
-
- struct TAddr {
- TString Hostname;
- time_t Resolved = 0;
- time_t NotFound = 0;
- TAtomic InProgress = 0;
- };
- /* IRemoteAddr is annoingly hard to use, so I'll use in6_addr as key
- * and put v4 addrs in it.
- */
- struct TAddrCmp {
- bool operator()(const in6_addr& left, const in6_addr& right) const {
- for (size_t i = 0; i < sizeof(left); i++) {
- if (left.s6_addr[i] < right.s6_addr[i]) {
- return true;
- } else if (left.s6_addr[i] > right.s6_addr[i]) {
- return false;
- }
- }
- // equal
- return false;
- }
- };
- typedef TMap<in6_addr, TAddr, TAddrCmp> TAddrCache;
-
- const THost& Resolve(const TString&, int family, bool cacheOnly = false);
-
- const TAddr& ResolveAddr(const in6_addr&, int family);
-
- void WaitTask(TAtomic&);
-
- static void GHBNCallback(void* arg, int status, int timeouts,
- struct hostent* info);
-
- static void GHBACallback(void* arg, int status, int timeouts,
- struct hostent* info);
-
- const time_t EntryLifetime;
- const time_t NegativeLifetime;
- const TDuration Timeout;
- const bool AllowIpV4;
- const bool AllowIpV6;
-
- TMutex CacheMtx;
- THostCache HostCache;
- TAddrCache AddrCache;
- ui64 ACacheHits;
- ui64 ACacheMisses;
- ui64 PtrCacheHits;
- ui64 PtrCacheMisses;
-
- const static THost NullHost;
-
- TMutex AresMtx;
- void* Channel;
-
- struct TAresLibInit {
- TAresLibInit();
- ~TAresLibInit();
- };
-
- static TAresLibInit InitAresLib;
-};
diff --git a/library/cpp/actors/dnscachelib/probes.cpp b/library/cpp/actors/dnscachelib/probes.cpp
deleted file mode 100644
index 07734ab20f..0000000000
--- a/library/cpp/actors/dnscachelib/probes.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "probes.h"
-
-LWTRACE_DEFINE_PROVIDER(DNSCACHELIB_PROVIDER)
diff --git a/library/cpp/actors/dnscachelib/probes.h b/library/cpp/actors/dnscachelib/probes.h
deleted file mode 100644
index 313b7b8712..0000000000
--- a/library/cpp/actors/dnscachelib/probes.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <library/cpp/lwtrace/all.h>
-
-#define DNSCACHELIB_PROVIDER(PROBE, EVENT, GROUPS, TYPES, NAMES) \
- PROBE(Created, GROUPS(), TYPES(), NAMES()) \
- PROBE(Destroyed, GROUPS(), TYPES(), NAMES()) \
- PROBE(AresInitFailed, GROUPS(), TYPES(), NAMES()) \
- PROBE(FamilyMismatch, \
- GROUPS(), \
- TYPES(int, bool, bool), \
- NAMES("family", "allowIpV4", "allowIpV6")) \
- PROBE(ResolveNullHost, \
- GROUPS(), \
- TYPES(TString, int), \
- NAMES("hostname", "family")) \
- PROBE(ResolveFromCache, \
- GROUPS(), \
- TYPES(TString, int, TString, TString, ui64), \
- NAMES("hostname", "family", "addrsV4", "addrsV6", "aCacheHits")) \
- PROBE(ResolveDone, \
- GROUPS(), \
- TYPES(TString, int, TString, TString), \
- NAMES("hostname", "family", "addrsV4", "addrsV6")) \
- PROBE(ResolveCacheTimeout, \
- GROUPS(), \
- TYPES(TString), \
- NAMES("hostname")) \
- PROBE(ResolveCacheNew, \
- GROUPS(), \
- TYPES(TString), \
- NAMES("hostname")) \
- /**/
-
-LWTRACE_DECLARE_PROVIDER(DNSCACHELIB_PROVIDER)
diff --git a/library/cpp/actors/dnscachelib/timekeeper.h b/library/cpp/actors/dnscachelib/timekeeper.h
deleted file mode 100644
index 0528d8549c..0000000000
--- a/library/cpp/actors/dnscachelib/timekeeper.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#pragma once
-
-#include <util/datetime/base.h>
-#include <util/generic/singleton.h>
-#include <util/string/cast.h>
-#include <util/system/thread.h>
-#include <util/system/event.h>
-#include <util/system/env.h>
-
-#include <cstdlib>
-
-/* Keeps current time accurate up to 1/10 second */
-
-class TTimeKeeper {
-public:
- static TInstant GetNow(void) {
- return TInstant::MicroSeconds(GetTime());
- }
-
- static time_t GetTime(void) {
- return Singleton<TTimeKeeper>()->CurrentTime.tv_sec;
- }
-
- static const struct timeval& GetTimeval(void) {
- return Singleton<TTimeKeeper>()->CurrentTime;
- }
-
- TTimeKeeper()
- : Thread(&TTimeKeeper::Worker, this)
- {
- ConstTime = !!GetEnv("TEST_TIME");
- if (ConstTime) {
- try {
- CurrentTime.tv_sec = FromString<ui32>(GetEnv("TEST_TIME"));
- } catch (TFromStringException exc) {
- ConstTime = false;
- }
- }
- if (!ConstTime) {
- gettimeofday(&CurrentTime, nullptr);
- Thread.Start();
- }
- }
-
- ~TTimeKeeper() {
- if (!ConstTime) {
- Exit.Signal();
- Thread.Join();
- }
- }
-
-private:
- static const ui32 UpdateInterval = 100000;
- struct timeval CurrentTime;
- bool ConstTime;
- TSystemEvent Exit;
- TThread Thread;
-
- static void* Worker(void* arg) {
- TTimeKeeper* owner = static_cast<TTimeKeeper*>(arg);
-
- do {
- /* Race condition may occur here but locking looks too expensive */
-
- gettimeofday(&owner->CurrentTime, nullptr);
- } while (!owner->Exit.WaitT(TDuration::MicroSeconds(UpdateInterval)));
-
- return nullptr;
- }
-};
diff --git a/library/cpp/actors/dnscachelib/ya.make b/library/cpp/actors/dnscachelib/ya.make
deleted file mode 100644
index 62eaafc8f5..0000000000
--- a/library/cpp/actors/dnscachelib/ya.make
+++ /dev/null
@@ -1,23 +0,0 @@
-LIBRARY()
-
-SRCS(
- dnscache.cpp
- dnscache.h
- probes.cpp
- probes.h
- timekeeper.h
-)
-
-PEERDIR(
- contrib/libs/c-ares
- library/cpp/lwtrace
- library/cpp/deprecated/atomic
-)
-
-IF (NOT EXPORT_CMAKE)
- ADDINCL(
- contrib/libs/c-ares/include
- )
-ENDIF()
-
-END()
diff --git a/library/cpp/actors/dnsresolver/CMakeLists.darwin-arm64.txt b/library/cpp/actors/dnsresolver/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 30d19f1b99..0000000000
--- a/library/cpp/actors/dnsresolver/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-dnsresolver)
-target_link_libraries(cpp-actors-dnsresolver PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- contrib-libs-c-ares
-)
-target_sources(cpp-actors-dnsresolver PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ondemand.cpp
-)
diff --git a/library/cpp/actors/dnsresolver/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/dnsresolver/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 30d19f1b99..0000000000
--- a/library/cpp/actors/dnsresolver/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-dnsresolver)
-target_link_libraries(cpp-actors-dnsresolver PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- contrib-libs-c-ares
-)
-target_sources(cpp-actors-dnsresolver PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ondemand.cpp
-)
diff --git a/library/cpp/actors/dnsresolver/CMakeLists.linux-aarch64.txt b/library/cpp/actors/dnsresolver/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index f7dbdca2ef..0000000000
--- a/library/cpp/actors/dnsresolver/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-dnsresolver)
-target_link_libraries(cpp-actors-dnsresolver PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- contrib-libs-c-ares
-)
-target_sources(cpp-actors-dnsresolver PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ondemand.cpp
-)
diff --git a/library/cpp/actors/dnsresolver/CMakeLists.linux-x86_64.txt b/library/cpp/actors/dnsresolver/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index f7dbdca2ef..0000000000
--- a/library/cpp/actors/dnsresolver/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-dnsresolver)
-target_link_libraries(cpp-actors-dnsresolver PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- contrib-libs-c-ares
-)
-target_sources(cpp-actors-dnsresolver PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ondemand.cpp
-)
diff --git a/library/cpp/actors/dnsresolver/CMakeLists.txt b/library/cpp/actors/dnsresolver/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/dnsresolver/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/dnsresolver/CMakeLists.windows-x86_64.txt b/library/cpp/actors/dnsresolver/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 30d19f1b99..0000000000
--- a/library/cpp/actors/dnsresolver/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-dnsresolver)
-target_link_libraries(cpp-actors-dnsresolver PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- contrib-libs-c-ares
-)
-target_sources(cpp-actors-dnsresolver PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ondemand.cpp
-)
diff --git a/library/cpp/actors/dnsresolver/dnsresolver.cpp b/library/cpp/actors/dnsresolver/dnsresolver.cpp
deleted file mode 100644
index d7d8c0e3b6..0000000000
--- a/library/cpp/actors/dnsresolver/dnsresolver.cpp
+++ /dev/null
@@ -1,485 +0,0 @@
-#include "dnsresolver.h"
-
-#include <library/cpp/actors/core/actorsystem.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/threading/queue/mpsc_htswap.h>
-#include <util/network/pair.h>
-#include <util/network/socket.h>
-#include <util/string/builder.h>
-#include <util/system/thread.h>
-
-#include <ares.h>
-
-#include <atomic>
-
-namespace NActors {
-namespace NDnsResolver {
-
- class TAresLibraryInitBase {
- protected:
- TAresLibraryInitBase() noexcept {
- int status = ares_library_init(ARES_LIB_INIT_ALL);
- Y_ABORT_UNLESS(status == ARES_SUCCESS, "Unexpected failure to initialize c-ares library");
- }
-
- ~TAresLibraryInitBase() noexcept {
- ares_library_cleanup();
- }
- };
-
- class TCallbackQueueBase {
- protected:
- TCallbackQueueBase() noexcept {
- int err = SocketPair(Sockets, false, true);
- Y_ABORT_UNLESS(err == 0, "Unexpected failure to create a socket pair");
- SetNonBlock(Sockets[0]);
- SetNonBlock(Sockets[1]);
- }
-
- ~TCallbackQueueBase() noexcept {
- closesocket(Sockets[0]);
- closesocket(Sockets[1]);
- }
-
- protected:
- using TCallback = std::function<void()>;
- using TCallbackQueue = NThreading::THTSwapQueue<TCallback>;
-
- void PushCallback(TCallback callback) {
- Y_ABORT_UNLESS(callback, "Cannot push an empty callback");
- CallbackQueue.Push(std::move(callback)); // this is a lockfree queue
-
- // Wake up worker thread on the first activation
- if (Activations.fetch_add(1, std::memory_order_acq_rel) == 0) {
- char ch = 'x';
- ssize_t ret;
-#ifdef _win_
- ret = send(SignalSock(), &ch, 1, 0);
- if (ret == -1) {
- Y_ABORT_UNLESS(WSAGetLastError() == WSAEWOULDBLOCK, "Unexpected send error");
- return;
- }
-#else
- do {
- ret = send(SignalSock(), &ch, 1, 0);
- } while (ret == -1 && errno == EINTR);
- if (ret == -1) {
- Y_ABORT_UNLESS(errno == EAGAIN || errno == EWOULDBLOCK, "Unexpected send error");
- return;
- }
-#endif
- Y_ABORT_UNLESS(ret == 1, "Unexpected send result");
- }
- }
-
- void RunCallbacks() noexcept {
- char ch[32];
- ssize_t ret;
- bool signalled = false;
- for (;;) {
- ret = recv(WaitSock(), ch, sizeof(ch), 0);
- if (ret > 0) {
- signalled = true;
- }
- if (ret == sizeof(ch)) {
- continue;
- }
- if (ret != -1) {
- break;
- }
-#ifdef _win_
- if (WSAGetLastError() == WSAEWOULDBLOCK) {
- break;
- }
- Y_ABORT("Unexpected recv error");
-#else
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- break;
- }
- Y_ABORT_UNLESS(errno == EINTR, "Unexpected recv error");
-#endif
- }
-
- if (signalled) {
- // There's exactly one write to SignalSock while Activations != 0
- // It's impossible to get signalled while Activations == 0
- // We must set Activations = 0 to receive new signals
- size_t count = Activations.exchange(0, std::memory_order_acq_rel);
- Y_ABORT_UNLESS(count != 0);
-
- // N.B. due to the way HTSwap works we may not be able to pop
- // all callbacks on this activation, however we expect a new
- // delayed activation to happen at a later time.
- while (auto callback = CallbackQueue.Pop()) {
- callback();
- }
- }
- }
-
- SOCKET SignalSock() {
- return Sockets[0];
- }
-
- SOCKET WaitSock() {
- return Sockets[1];
- }
-
- private:
- SOCKET Sockets[2];
- TCallbackQueue CallbackQueue;
- std::atomic<size_t> Activations{ 0 };
- };
-
- class TSimpleDnsResolver
- : public TActor<TSimpleDnsResolver>
- , private TAresLibraryInitBase
- , private TCallbackQueueBase
- {
- public:
- TSimpleDnsResolver(TSimpleDnsResolverOptions options) noexcept
- : TActor(&TThis::StateWork)
- , Options(std::move(options))
- , WorkerThread(&TThis::WorkerThreadStart, this)
- {
- InitAres();
-
- WorkerThread.Start();
- }
-
- ~TSimpleDnsResolver() noexcept override {
- if (!Stopped) {
- PushCallback([this] {
- // Mark as stopped first
- Stopped = true;
-
- // Cancel all current ares requests (will not send replies)
- ares_cancel(AresChannel);
- });
-
- WorkerThread.Join();
- }
-
- StopAres();
- }
-
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::DNS_RESOLVER;
- }
-
- private:
- void InitAres() noexcept {
- struct ares_options options;
- memset(&options, 0, sizeof(options));
- int optmask = 0;
-
- options.flags = ARES_FLAG_STAYOPEN;
- optmask |= ARES_OPT_FLAGS;
-
- options.sock_state_cb = &TThis::SockStateCallback;
- options.sock_state_cb_data = this;
- optmask |= ARES_OPT_SOCK_STATE_CB;
-
- options.timeout = Options.Timeout.MilliSeconds();
- if (options.timeout > 0) {
- optmask |= ARES_OPT_TIMEOUTMS;
- }
-
- options.tries = Options.Attempts;
- if (options.tries > 0) {
- optmask |= ARES_OPT_TRIES;
- }
-
- int err = ares_init_options(&AresChannel, &options, optmask);
- Y_ABORT_UNLESS(err == 0, "Unexpected failure to initialize c-ares channel");
-
- if (Options.Servers) {
- TStringBuilder csv;
- for (const TString& server : Options.Servers) {
- if (csv) {
- csv << ',';
- }
- csv << server;
- }
- err = ares_set_servers_ports_csv(AresChannel, csv.c_str());
- Y_ABORT_UNLESS(err == 0, "Unexpected failure to set a list of dns servers: %s", ares_strerror(err));
- }
- }
-
- void StopAres() noexcept {
- // Destroy the ares channel
- ares_destroy(AresChannel);
- AresChannel = nullptr;
- }
-
- private:
- STRICT_STFUNC(StateWork, {
- hFunc(TEvents::TEvPoison, Handle);
- hFunc(TEvDns::TEvGetHostByName, Handle);
- hFunc(TEvDns::TEvGetAddr, Handle);
- })
-
- void Handle(TEvents::TEvPoison::TPtr&) {
- Y_ABORT_UNLESS(!Stopped);
-
- PushCallback([this] {
- // Cancel all current ares requests (will send notifications)
- ares_cancel(AresChannel);
-
- // Mark as stopped last
- Stopped = true;
- });
-
- WorkerThread.Join();
- PassAway();
- }
-
- private:
- enum class ERequestType {
- GetHostByName,
- GetAddr,
- };
-
- struct TRequestContext : public TThrRefBase {
- using TPtr = TIntrusivePtr<TRequestContext>;
-
- TThis* Self;
- TActorSystem* ActorSystem;
- TActorId SelfId;
- TActorId Sender;
- ui64 Cookie;
- ERequestType Type;
-
- TRequestContext(TThis* self, TActorSystem* as, TActorId selfId, TActorId sender, ui64 cookie, ERequestType type)
- : Self(self)
- , ActorSystem(as)
- , SelfId(selfId)
- , Sender(sender)
- , Cookie(cookie)
- , Type(type)
- { }
- };
-
- private:
- void Handle(TEvDns::TEvGetHostByName::TPtr& ev) {
- auto* msg = ev->Get();
- auto reqCtx = MakeIntrusive<TRequestContext>(
- this, TActivationContext::ActorSystem(), SelfId(), ev->Sender, ev->Cookie, ERequestType::GetHostByName);
- PushCallback([this, reqCtx = std::move(reqCtx), name = std::move(msg->Name), family = msg->Family] () mutable {
- StartGetAddrInfo(std::move(reqCtx), std::move(name), family);
- });
- }
-
- void Handle(TEvDns::TEvGetAddr::TPtr& ev) {
- auto* msg = ev->Get();
- auto reqCtx = MakeIntrusive<TRequestContext>(
- this, TActivationContext::ActorSystem(), SelfId(), ev->Sender, ev->Cookie, ERequestType::GetAddr);
- PushCallback([this, reqCtx = std::move(reqCtx), name = std::move(msg->Name), family = msg->Family] () mutable {
- StartGetAddrInfo(std::move(reqCtx), std::move(name), family);
- });
- }
-
- void StartGetAddrInfo(TRequestContext::TPtr reqCtx, TString name, int family) noexcept {
- reqCtx->Ref();
- ares_addrinfo_hints hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = ARES_AI_NOSORT;
- hints.ai_family = family;
- ares_getaddrinfo(AresChannel, name.c_str(), nullptr, &hints, &TThis::GetAddrInfoAresCallback, reqCtx.Get());
- }
-
- private:
- static void GetAddrInfoAresCallback(void* arg, int status, int timeouts, ares_addrinfo *result) {
- struct TDeleter {
- void operator ()(ares_addrinfo *ptr) const {
- ares_freeaddrinfo(ptr);
- }
- };
- std::unique_ptr<ares_addrinfo, TDeleter> ptr(result);
-
- Y_UNUSED(timeouts);
- TRequestContext::TPtr reqCtx(static_cast<TRequestContext*>(arg));
- reqCtx->UnRef();
-
- if (reqCtx->Self->Stopped) {
- // Don't send any replies after destruction
- return;
- }
-
- switch (reqCtx->Type) {
- case ERequestType::GetHostByName: {
- auto result = MakeHolder<TEvDns::TEvGetHostByNameResult>();
- if (status == ARES_SUCCESS) {
- for (auto *node = ptr->nodes; node; node = node->ai_next) {
- switch (node->ai_family) {
- case AF_INET: {
- result->AddrsV4.emplace_back(((sockaddr_in*)node->ai_addr)->sin_addr);
- break;
- }
- case AF_INET6: {
- result->AddrsV6.emplace_back(((sockaddr_in6*)node->ai_addr)->sin6_addr);
- break;
- }
- default:
- Y_ABORT("unknown address family in ares callback");
- }
- }
- } else {
- result->ErrorText = ares_strerror(status);
- }
- result->Status = status;
-
- reqCtx->ActorSystem->Send(new IEventHandle(reqCtx->Sender, reqCtx->SelfId, result.Release(), 0, reqCtx->Cookie));
- break;
- }
-
- case ERequestType::GetAddr: {
- auto result = MakeHolder<TEvDns::TEvGetAddrResult>();
- if (status == ARES_SUCCESS && Y_UNLIKELY(ptr->nodes == nullptr)) {
- status = ARES_ENODATA;
- }
- if (status == ARES_SUCCESS) {
- auto *node = ptr->nodes;
- switch (node->ai_family) {
- case AF_INET: {
- result->Addr = ((sockaddr_in*)node->ai_addr)->sin_addr;
- break;
- }
- case AF_INET6: {
- result->Addr = ((sockaddr_in6*)node->ai_addr)->sin6_addr;
- break;
- }
- default:
- Y_ABORT("unknown address family in ares callback");
- }
- } else {
- result->ErrorText = ares_strerror(status);
- }
- result->Status = status;
-
- reqCtx->ActorSystem->Send(new IEventHandle(reqCtx->Sender, reqCtx->SelfId, result.Release(), 0, reqCtx->Cookie));
- break;
- }
- }
- }
-
- private:
- static void SockStateCallback(void* data, ares_socket_t socket_fd, int readable, int writable) {
- static_cast<TThis*>(data)->DoSockStateCallback(socket_fd, readable, writable);
- }
-
- void DoSockStateCallback(ares_socket_t socket_fd, int readable, int writable) noexcept {
- int events = (readable ? (POLLRDNORM | POLLIN) : 0) | (writable ? (POLLWRNORM | POLLOUT) : 0);
- if (events == 0) {
- AresSockStates.erase(socket_fd);
- } else {
- AresSockStates[socket_fd].NeededEvents = events;
- }
- }
-
- private:
- static void* WorkerThreadStart(void* arg) noexcept {
- static_cast<TSimpleDnsResolver*>(arg)->WorkerThreadLoop();
- return nullptr;
- }
-
- void WorkerThreadLoop() noexcept {
- TThread::SetCurrentThreadName("DnsResolver");
-
- TVector<struct pollfd> fds;
- while (!Stopped) {
- fds.clear();
- fds.reserve(1 + AresSockStates.size());
- {
- auto& entry = fds.emplace_back();
- entry.fd = WaitSock();
- entry.events = POLLRDNORM | POLLIN;
- }
- for (auto& kv : AresSockStates) {
- auto& entry = fds.emplace_back();
- entry.fd = kv.first;
- entry.events = kv.second.NeededEvents;
- }
-
- int timeout = -1;
- struct timeval tv;
- if (ares_timeout(AresChannel, nullptr, &tv)) {
- timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000;
- }
-
- int ret = poll(fds.data(), fds.size(), timeout);
- if (ret == -1) {
- if (errno == EINTR) {
- continue;
- }
- // we cannot handle failures, run callbacks and pretend everything is ok
- RunCallbacks();
- if (Stopped) {
- break;
- }
- ret = 0;
- }
-
- bool ares_called = false;
- if (ret > 0) {
- for (size_t i = 0; i < fds.size(); ++i) {
- auto& entry = fds[i];
-
- // Handle WaitSock activation and run callbacks
- if (i == 0) {
- if (entry.revents & (POLLRDNORM | POLLIN)) {
- RunCallbacks();
- if (Stopped) {
- break;
- }
- }
- continue;
- }
-
- // All other sockets belong to ares
- if (entry.revents == 0) {
- continue;
- }
- // Previous invocation of aress_process_fd might have removed some sockets
- if (Y_UNLIKELY(!AresSockStates.contains(entry.fd))) {
- continue;
- }
- ares_process_fd(
- AresChannel,
- entry.revents & (POLLRDNORM | POLLIN) ? entry.fd : ARES_SOCKET_BAD,
- entry.revents & (POLLWRNORM | POLLOUT) ? entry.fd : ARES_SOCKET_BAD);
- ares_called = true;
- }
-
- if (Stopped) {
- break;
- }
- }
-
- if (!ares_called) {
- // Let ares handle timeouts
- ares_process_fd(AresChannel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
- }
- }
- }
-
- private:
- struct TSockState {
- short NeededEvents = 0; // poll events
- };
-
- private:
- TSimpleDnsResolverOptions Options;
- TThread WorkerThread;
-
- ares_channel AresChannel;
- THashMap<SOCKET, TSockState> AresSockStates;
-
- bool Stopped = false;
- };
-
- IActor* CreateSimpleDnsResolver(TSimpleDnsResolverOptions options) {
- return new TSimpleDnsResolver(std::move(options));
- }
-
-} // namespace NDnsResolver
-} // namespace NActors
diff --git a/library/cpp/actors/dnsresolver/dnsresolver.h b/library/cpp/actors/dnsresolver/dnsresolver.h
deleted file mode 100644
index 1121c31e51..0000000000
--- a/library/cpp/actors/dnsresolver/dnsresolver.h
+++ /dev/null
@@ -1,128 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/actors/core/event_local.h>
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-#include <util/network/address.h>
-#include <variant>
-
-namespace NActors {
-namespace NDnsResolver {
-
- struct TEvDns {
- enum EEv {
- EvGetHostByName = EventSpaceBegin(TEvents::ES_DNS),
- EvGetHostByNameResult,
- EvGetAddr,
- EvGetAddrResult,
- };
-
- /**
- * TEvGetHostByName returns the result of ares_gethostbyname
- */
- struct TEvGetHostByName : public TEventLocal<TEvGetHostByName, EvGetHostByName> {
- TString Name;
- int Family;
-
- explicit TEvGetHostByName(TString name, int family = AF_UNSPEC)
- : Name(std::move(name))
- , Family(family)
- { }
- };
-
- struct TEvGetHostByNameResult : public TEventLocal<TEvGetHostByNameResult, EvGetHostByNameResult> {
- TVector<struct in_addr> AddrsV4;
- TVector<struct in6_addr> AddrsV6;
- TString ErrorText;
- int Status = 0;
- };
-
- /**
- * TEvGetAddr returns a single address for a given hostname
- */
- struct TEvGetAddr : public TEventLocal<TEvGetAddr, EvGetAddr> {
- TString Name;
- int Family;
-
- explicit TEvGetAddr(TString name, int family = AF_UNSPEC)
- : Name(std::move(name))
- , Family(family)
- { }
- };
-
- struct TEvGetAddrResult : public TEventLocal<TEvGetAddrResult, EvGetAddrResult> {
- // N.B. "using" here doesn't work with Visual Studio compiler
- typedef struct in6_addr TIPv6Addr;
- typedef struct in_addr TIPv4Addr;
-
- std::variant<std::monostate, TIPv6Addr, TIPv4Addr> Addr;
- TString ErrorText;
- int Status = 0;
-
- bool IsV6() const {
- return std::holds_alternative<TIPv6Addr>(Addr);
- }
-
- bool IsV4() const {
- return std::holds_alternative<TIPv4Addr>(Addr);
- }
-
- const TIPv6Addr& GetAddrV6() const {
- const TIPv6Addr* p = std::get_if<TIPv6Addr>(&Addr);
- Y_ABORT_UNLESS(p, "Result is not an ipv6 address");
- return *p;
- }
-
- const TIPv4Addr& GetAddrV4() const {
- const TIPv4Addr* p = std::get_if<TIPv4Addr>(&Addr);
- Y_ABORT_UNLESS(p, "Result is not an ipv4 address");
- return *p;
- }
- };
- };
-
- struct TSimpleDnsResolverOptions {
- // Initial per-server timeout, grows exponentially with each retry
- TDuration Timeout = TDuration::Seconds(1);
- // Number of attempts per-server
- int Attempts = 2;
- // Optional list of custom dns servers (ip.v4[:port], ip::v6 or [ip::v6]:port format)
- TVector<TString> Servers;
- };
-
- IActor* CreateSimpleDnsResolver(TSimpleDnsResolverOptions options = TSimpleDnsResolverOptions());
-
- struct TCachingDnsResolverOptions {
- // Soft expire time specifies delay before name is refreshed in background
- TDuration SoftNegativeExpireTime = TDuration::Seconds(1);
- TDuration SoftPositiveExpireTime = TDuration::Seconds(10);
- // Hard expire time specifies delay before the last result is forgotten
- TDuration HardNegativeExpireTime = TDuration::Seconds(10);
- TDuration HardPositiveExpireTime = TDuration::Hours(2);
- // Allow these request families
- bool AllowIPv6 = true;
- bool AllowIPv4 = true;
- // Optional counters
- NMonitoring::TDynamicCounterPtr MonCounters = nullptr;
- };
-
- IActor* CreateCachingDnsResolver(TActorId upstream, TCachingDnsResolverOptions options = TCachingDnsResolverOptions());
-
- struct TOnDemandDnsResolverOptions
- : public TSimpleDnsResolverOptions
- , public TCachingDnsResolverOptions
- {
- };
-
- IActor* CreateOnDemandDnsResolver(TOnDemandDnsResolverOptions options = TOnDemandDnsResolverOptions());
-
- /**
- * Returns actor id of a globally registered dns resolver
- */
- inline TActorId MakeDnsResolverActorId() {
- return TActorId(0, TStringBuf("dnsresolver"));
- }
-
-} // namespace NDnsResolver
-} // namespace NActors
diff --git a/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp b/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
deleted file mode 100644
index 83b1847962..0000000000
--- a/library/cpp/actors/dnsresolver/dnsresolver_caching.cpp
+++ /dev/null
@@ -1,694 +0,0 @@
-#include "dnsresolver.h"
-
-#include <library/cpp/actors/core/hfunc.h>
-#include <util/generic/intrlist.h>
-
-#include <ares.h>
-
-#include <queue>
-
-namespace NActors {
-namespace NDnsResolver {
-
- class TCachingDnsResolver : public TActor<TCachingDnsResolver> {
- public:
- struct TMonCounters {
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingInFlightV4;
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingInFlightV6;
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingInFlightUnspec;
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingErrorsV4;
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingErrorsV6;
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingErrorsUnspec;
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingTotalV4;
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingTotalV6;
- NMonitoring::TDynamicCounters::TCounterPtr OutgoingTotalUnspec;
-
- NMonitoring::TDynamicCounters::TCounterPtr IncomingInFlight;
- NMonitoring::TDynamicCounters::TCounterPtr IncomingErrors;
- NMonitoring::TDynamicCounters::TCounterPtr IncomingTotal;
-
- NMonitoring::TDynamicCounters::TCounterPtr CacheSize;
- NMonitoring::TDynamicCounters::TCounterPtr CacheHits;
- NMonitoring::TDynamicCounters::TCounterPtr CacheMisses;
-
- TMonCounters(const NMonitoring::TDynamicCounterPtr& counters)
- : OutgoingInFlightV4(counters->GetCounter("DnsResolver/Outgoing/InFlight/V4", false))
- , OutgoingInFlightV6(counters->GetCounter("DnsResolver/Outgoing/InFlight/V6", false))
- , OutgoingInFlightUnspec(counters->GetCounter("DnsResolver/Outgoing/InFlight/Unspec", false))
- , OutgoingErrorsV4(counters->GetCounter("DnsResolver/Outgoing/Errors/V4", true))
- , OutgoingErrorsV6(counters->GetCounter("DnsResolver/Outgoing/Errors/V6", true))
- , OutgoingErrorsUnspec(counters->GetCounter("DnsResolver/Outgoing/Errors/Unspec", true))
- , OutgoingTotalV4(counters->GetCounter("DnsResolver/Outgoing/Total/V4", true))
- , OutgoingTotalV6(counters->GetCounter("DnsResolver/Outgoing/Total/V6", true))
- , OutgoingTotalUnspec(counters->GetCounter("DnsResolver/Outgoing/Total/Unspec", true))
- , IncomingInFlight(counters->GetCounter("DnsResolver/Incoming/InFlight", false))
- , IncomingErrors(counters->GetCounter("DnsResolver/Incoming/Errors", true))
- , IncomingTotal(counters->GetCounter("DnsResolver/Incoming/Total", true))
- , CacheSize(counters->GetCounter("DnsResolver/Cache/Size", false))
- , CacheHits(counters->GetCounter("DnsResolver/Cache/Hits", true))
- , CacheMisses(counters->GetCounter("DnsResolver/Cache/Misses", true))
- { }
-
- const NMonitoring::TDynamicCounters::TCounterPtr& OutgoingInFlightByFamily(int family) const {
- switch (family) {
- case AF_INET:
- return OutgoingInFlightV4;
- case AF_INET6:
- return OutgoingInFlightV6;
- case AF_UNSPEC:
- return OutgoingInFlightUnspec;
- default:
- Y_ABORT("Unexpected family %d", family);
- }
- }
-
- const NMonitoring::TDynamicCounters::TCounterPtr& OutgoingErrorsByFamily(int family) const {
- switch (family) {
- case AF_INET:
- return OutgoingErrorsV4;
- case AF_INET6:
- return OutgoingErrorsV6;
- case AF_UNSPEC:
- return OutgoingErrorsUnspec;
- default:
- Y_ABORT("Unexpected family %d", family);
- }
- }
-
- const NMonitoring::TDynamicCounters::TCounterPtr& OutgoingTotalByFamily(int family) const {
- switch (family) {
- case AF_INET:
- return OutgoingTotalV4;
- case AF_INET6:
- return OutgoingTotalV6;
- case AF_UNSPEC:
- return OutgoingTotalUnspec;
- default:
- Y_ABORT("Unexpected family %d", family);
- }
- }
- };
-
- public:
- TCachingDnsResolver(TActorId upstream, TCachingDnsResolverOptions options)
- : TActor(&TThis::StateWork)
- , Upstream(upstream)
- , Options(std::move(options))
- , MonCounters(Options.MonCounters ? new TMonCounters(Options.MonCounters) : nullptr)
- { }
-
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::DNS_RESOLVER;
- }
-
- private:
- STRICT_STFUNC(StateWork, {
- hFunc(TEvents::TEvPoison, Handle);
- hFunc(TEvDns::TEvGetHostByName, Handle);
- hFunc(TEvDns::TEvGetAddr, Handle);
- hFunc(TEvDns::TEvGetHostByNameResult, Handle);
- hFunc(TEvents::TEvUndelivered, Handle);
- });
-
- void Handle(TEvents::TEvPoison::TPtr&) {
- DropPending(ARES_ECANCELLED);
- PassAway();
- }
-
- void Handle(TEvDns::TEvGetHostByName::TPtr& ev) {
- auto req = MakeHolder<TIncomingRequest>();
- req->Type = EIncomingRequestType::GetHostByName;
- req->Sender = ev->Sender;
- req->Cookie = ev->Cookie;
- req->Name = std::move(ev->Get()->Name);
- req->Family = ev->Get()->Family;
- EnqueueRequest(std::move(req));
- }
-
- void Handle(TEvDns::TEvGetAddr::TPtr& ev) {
- auto req = MakeHolder<TIncomingRequest>();
- req->Type = EIncomingRequestType::GetAddr;
- req->Sender = ev->Sender;
- req->Cookie = ev->Cookie;
- req->Name = std::move(ev->Get()->Name);
- req->Family = ev->Get()->Family;
- EnqueueRequest(std::move(req));
- }
-
- void Handle(TEvDns::TEvGetHostByNameResult::TPtr& ev) {
- auto waitingIt = WaitingRequests.find(ev->Cookie);
- Y_ABORT_UNLESS(waitingIt != WaitingRequests.end(), "Unexpected reply, reqId=%" PRIu64, ev->Cookie);
- auto waitingInfo = waitingIt->second;
- WaitingRequests.erase(waitingIt);
-
- switch (waitingInfo.Family) {
- case AF_UNSPEC:
- case AF_INET6:
- case AF_INET:
- if (ev->Get()->Status) {
- ProcessError(waitingInfo.Family, waitingInfo.Position, ev->Get()->Status, std::move(ev->Get()->ErrorText));
- } else {
- ProcessAddrs(waitingInfo.Family, waitingInfo.Position, std::move(ev->Get()->AddrsV6), std::move(ev->Get()->AddrsV4));
- }
- break;
-
- default:
- Y_ABORT("Unexpected request family %d", waitingInfo.Family);
- }
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr& ev) {
- switch (ev->Get()->SourceType) {
- case TEvDns::TEvGetHostByName::EventType: {
- auto waitingIt = WaitingRequests.find(ev->Cookie);
- Y_ABORT_UNLESS(waitingIt != WaitingRequests.end(), "Unexpected TEvUndelivered, reqId=%" PRIu64, ev->Cookie);
- auto waitingInfo = waitingIt->second;
- WaitingRequests.erase(waitingIt);
-
- switch (waitingInfo.Family) {
- case AF_UNSPEC:
- case AF_INET6:
- case AF_INET:
- ProcessError(waitingInfo.Family, waitingInfo.Position, ARES_ENOTINITIALIZED, "Caching dns resolver cannot deliver to the underlying resolver");
- break;
-
- default:
- Y_ABORT("Unexpected request family %d", waitingInfo.Family);
- }
-
- break;
- }
-
- default:
- Y_ABORT("Unexpected TEvUndelievered, type=%" PRIu32, ev->Get()->SourceType);
- }
- }
-
- private:
- enum EIncomingRequestType {
- GetHostByName,
- GetAddr,
- };
-
- struct TIncomingRequest : public TIntrusiveListItem<TIncomingRequest> {
- EIncomingRequestType Type;
- TActorId Sender;
- ui64 Cookie;
- TString Name;
- int Family;
- };
-
- using TIncomingRequestList = TIntrusiveListWithAutoDelete<TIncomingRequest, TDelete>;
-
- void EnqueueRequest(THolder<TIncomingRequest> req) {
- if (MonCounters) {
- ++*MonCounters->IncomingTotal;
- }
-
- CleanupExpired(TActivationContext::Now());
-
- switch (req->Family) {
- case AF_UNSPEC:
- if (Options.AllowIPv6 && Options.AllowIPv4) {
- EnqueueRequest(AF_UNSPEC, std::move(req));
- return;
- }
- if (Options.AllowIPv6) {
- EnqueueRequest(AF_INET6, std::move(req));
- return;
- }
- if (Options.AllowIPv4) {
- EnqueueRequest(AF_INET, std::move(req));
- return;
- }
- break;
-
- case AF_INET6:
- if (Options.AllowIPv6) {
- EnqueueRequest(AF_INET6, std::move(req));
- return;
- }
- break;
-
- case AF_INET:
- if (Options.AllowIPv4) {
- EnqueueRequest(AF_INET, std::move(req));
- return;
- }
- break;
- }
-
- ReplyWithError(std::move(req), ARES_EBADFAMILY);
- }
-
- void EnqueueRequest(int family, THolder<TIncomingRequest> req) {
- auto now = TActivationContext::Now();
-
- auto& fullState = NameToState[req->Name];
- if (MonCounters) {
- *MonCounters->CacheSize = NameToState.size();
- }
-
- auto& state = fullState.StateByFamily(family);
- EnsureRequest(state, req->Name, family, now);
-
- if (state.IsHardExpired(now)) {
- Y_ABORT_UNLESS(state.Waiting);
- if (MonCounters) {
- ++*MonCounters->CacheMisses;
- }
- state.WaitingRequests.PushBack(req.Release());
- return;
- }
-
- if (MonCounters) {
- ++*MonCounters->CacheHits;
- }
-
- if (state.Status != 0) {
- ReplyWithError(std::move(req), state.Status, state.ErrorText);
- } else {
- ReplyWithAddrs(std::move(req), state.AddrsIPv6, state.AddrsIPv4);
- }
- }
-
- private:
- struct TFamilyState {
- TVector<struct in6_addr> AddrsIPv6;
- TVector<struct in_addr> AddrsIPv4;
- TIncomingRequestList WaitingRequests;
- TInstant SoftDeadline;
- TInstant HardDeadline;
- TInstant NextSoftDeadline;
- TInstant NextHardDeadline;
- TString ErrorText;
- int Status = -1; // never requested before
- bool InSoftHeap = false;
- bool InHardHeap = false;
- bool Waiting = false;
-
- bool Needed() const {
- return InSoftHeap || InHardHeap || Waiting;
- }
-
- bool ServerReplied() const {
- return ServerReplied(Status);
- }
-
- bool IsSoftExpired(TInstant now) const {
- return !InSoftHeap || NextSoftDeadline < now;
- }
-
- bool IsHardExpired(TInstant now) const {
- return !InHardHeap || NextHardDeadline < now;
- }
-
- static bool ServerReplied(int status) {
- return (
- status == ARES_SUCCESS ||
- status == ARES_ENODATA ||
- status == ARES_ENOTFOUND);
- }
- };
-
- struct TState {
- TFamilyState StateUnspec;
- TFamilyState StateIPv6;
- TFamilyState StateIPv4;
-
- bool Needed() const {
- return StateUnspec.Needed() || StateIPv6.Needed() || StateIPv4.Needed();
- }
-
- const TFamilyState& StateByFamily(int family) const {
- switch (family) {
- case AF_UNSPEC:
- return StateUnspec;
- case AF_INET6:
- return StateIPv6;
- case AF_INET:
- return StateIPv4;
- default:
- Y_ABORT("Unsupported family %d", family);
- }
- }
-
- TFamilyState& StateByFamily(int family) {
- switch (family) {
- case AF_UNSPEC:
- return StateUnspec;
- case AF_INET6:
- return StateIPv6;
- case AF_INET:
- return StateIPv4;
- default:
- Y_ABORT("Unsupported family %d", family);
- }
- }
- };
-
- using TNameToState = THashMap<TString, TState>;
-
- template<const TFamilyState TState::* StateToFamily,
- const TInstant TFamilyState::* FamilyToDeadline>
- struct THeapCompare {
- // returns true when b < a
- bool operator()(TNameToState::iterator a, TNameToState::iterator b) const {
- const TState& aState = a->second;
- const TState& bState = b->second;
- const TFamilyState& aFamily = aState.*StateToFamily;
- const TFamilyState& bFamily = bState.*StateToFamily;
- const TInstant& aDeadline = aFamily.*FamilyToDeadline;
- const TInstant& bDeadline = bFamily.*FamilyToDeadline;
- return bDeadline < aDeadline;
- }
- };
-
- template<const TFamilyState TState::* StateToFamily,
- const TInstant TFamilyState::* FamilyToDeadline>
- using TStateHeap = std::priority_queue<
- TNameToState::iterator,
- std::vector<TNameToState::iterator>,
- THeapCompare<StateToFamily, FamilyToDeadline>
- >;
-
- struct TWaitingInfo {
- TNameToState::iterator Position;
- int Family;
- };
-
- private:
- void EnsureRequest(TFamilyState& state, const TString& name, int family, TInstant now) {
- if (state.Waiting) {
- return; // request is already pending
- }
-
- if (!state.IsSoftExpired(now) && !state.IsHardExpired(now)) {
- return; // response is not expired yet
- }
-
- if (MonCounters) {
- ++*MonCounters->OutgoingInFlightByFamily(family);
- ++*MonCounters->OutgoingTotalByFamily(family);
- }
-
- ui64 reqId = ++LastRequestId;
- auto& req = WaitingRequests[reqId];
- req.Position = NameToState.find(name);
- req.Family = family;
- Y_ABORT_UNLESS(req.Position != NameToState.end());
-
- Send(Upstream, new TEvDns::TEvGetHostByName(name, family), IEventHandle::FlagTrackDelivery, reqId);
- state.Waiting = true;
- }
-
- template<TFamilyState TState::* StateToFamily,
- TInstant TFamilyState::* FamilyToDeadline,
- TInstant TFamilyState::* FamilyToNextDeadline,
- bool TFamilyState::* FamilyToFlag,
- class THeap>
- void PushToHeap(THeap& heap, TNameToState::iterator it, TInstant newDeadline) {
- auto& family = it->second.*StateToFamily;
- TInstant& deadline = family.*FamilyToDeadline;
- TInstant& nextDeadline = family.*FamilyToNextDeadline;
- bool& flag = family.*FamilyToFlag;
- nextDeadline = newDeadline;
- if (!flag) {
- deadline = newDeadline;
- heap.push(it);
- flag = true;
- }
- }
-
- void PushSoftUnspec(TNameToState::iterator it, TInstant newDeadline) {
- PushToHeap<&TState::StateUnspec, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapUnspec, it, newDeadline);
- }
-
- void PushHardUnspec(TNameToState::iterator it, TInstant newDeadline) {
- PushToHeap<&TState::StateUnspec, &TFamilyState::HardDeadline, &TFamilyState::NextHardDeadline, &TFamilyState::InHardHeap>(HardHeapUnspec, it, newDeadline);
- }
-
- void PushSoftV6(TNameToState::iterator it, TInstant newDeadline) {
- PushToHeap<&TState::StateIPv6, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapIPv6, it, newDeadline);
- }
-
- void PushHardV6(TNameToState::iterator it, TInstant newDeadline) {
- PushToHeap<&TState::StateIPv6, &TFamilyState::HardDeadline, &TFamilyState::NextHardDeadline, &TFamilyState::InHardHeap>(HardHeapIPv6, it, newDeadline);
- }
-
- void PushSoftV4(TNameToState::iterator it, TInstant newDeadline) {
- PushToHeap<&TState::StateIPv4, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapIPv4, it, newDeadline);
- }
-
- void PushHardV4(TNameToState::iterator it, TInstant newDeadline) {
- PushToHeap<&TState::StateIPv4, &TFamilyState::HardDeadline, &TFamilyState::NextHardDeadline, &TFamilyState::InHardHeap>(HardHeapIPv4, it, newDeadline);
- }
-
- void PushSoft(int family, TNameToState::iterator it, TInstant newDeadline) {
- switch (family) {
- case AF_UNSPEC:
- PushSoftUnspec(it, newDeadline);
- break;
- case AF_INET6:
- PushSoftV6(it, newDeadline);
- break;
- case AF_INET:
- PushSoftV4(it, newDeadline);
- break;
- default:
- Y_ABORT("Unexpected family %d", family);
- }
- }
-
- void PushHard(int family, TNameToState::iterator it, TInstant newDeadline) {
- switch (family) {
- case AF_UNSPEC:
- PushHardUnspec(it, newDeadline);
- break;
- case AF_INET6:
- PushHardV6(it, newDeadline);
- break;
- case AF_INET:
- PushHardV4(it, newDeadline);
- break;
- default:
- Y_ABORT("Unexpected family %d", family);
- }
- }
-
- void ProcessError(int family, TNameToState::iterator it, int status, TString errorText) {
- auto now = TActivationContext::Now();
- if (MonCounters) {
- --*MonCounters->OutgoingInFlightByFamily(family);
- ++*MonCounters->OutgoingErrorsByFamily(family);
- }
-
- auto& state = it->second.StateByFamily(family);
- Y_ABORT_UNLESS(state.Waiting, "Got error for a state we are not waiting");
- state.Waiting = false;
-
- // When we have a cached positive reply, don't overwrite it with spurious errors
- const bool serverReplied = TFamilyState::ServerReplied(status);
- if (!serverReplied && state.ServerReplied() && !state.IsHardExpired(now)) {
- PushSoft(family, it, now + Options.SoftNegativeExpireTime);
- if (state.Status == ARES_SUCCESS) {
- SendAddrs(family, it);
- } else {
- SendErrors(family, it);
- }
- return;
- }
-
- state.Status = status;
- state.ErrorText = std::move(errorText);
- PushSoft(family, it, now + Options.SoftNegativeExpireTime);
- if (serverReplied) {
- // Server actually replied, so keep it cached for longer
- PushHard(family, it, now + Options.HardPositiveExpireTime);
- } else {
- PushHard(family, it, now + Options.HardNegativeExpireTime);
- }
-
- SendErrors(family, it);
- }
-
- void SendErrors(int family, TNameToState::iterator it) {
- auto& state = it->second.StateByFamily(family);
- while (state.WaitingRequests) {
- THolder<TIncomingRequest> req(state.WaitingRequests.PopFront());
- ReplyWithError(std::move(req), state.Status, state.ErrorText);
- }
- }
-
- void ProcessAddrs(int family, TNameToState::iterator it, TVector<struct in6_addr> addrs6, TVector<struct in_addr> addrs4) {
- if (Y_UNLIKELY(addrs6.empty() && addrs4.empty())) {
- // Probably unnecessary: we don't want to deal with empty address lists
- return ProcessError(family, it, ARES_ENODATA, ares_strerror(ARES_ENODATA));
- }
-
- auto now = TActivationContext::Now();
- if (MonCounters) {
- --*MonCounters->OutgoingInFlightByFamily(family);
- }
-
- auto& state = it->second.StateByFamily(family);
- Y_ABORT_UNLESS(state.Waiting, "Got reply for a state we are not waiting");
- state.Waiting = false;
-
- state.Status = ARES_SUCCESS;
- state.AddrsIPv6 = std::move(addrs6);
- state.AddrsIPv4 = std::move(addrs4);
- PushSoft(family, it, now + Options.SoftPositiveExpireTime);
- PushHard(family, it, now + Options.HardPositiveExpireTime);
-
- SendAddrs(family, it);
- }
-
- void SendAddrs(int family, TNameToState::iterator it) {
- auto& state = it->second.StateByFamily(family);
- while (state.WaitingRequests) {
- THolder<TIncomingRequest> req(state.WaitingRequests.PopFront());
- ReplyWithAddrs(std::move(req), state.AddrsIPv6, state.AddrsIPv4);
- }
- }
-
- private:
- template<TFamilyState TState::*StateToFamily,
- TInstant TFamilyState::* FamilyToDeadline,
- TInstant TFamilyState::* FamilyToNextDeadline,
- bool TFamilyState::* FamilyToFlag>
- void DoCleanupExpired(TStateHeap<StateToFamily, FamilyToDeadline>& heap, TInstant now) {
- while (!heap.empty()) {
- auto it = heap.top();
- auto& family = it->second.*StateToFamily;
- TInstant& deadline = family.*FamilyToDeadline;
- if (now <= deadline) {
- break;
- }
-
- bool& flag = family.*FamilyToFlag;
- Y_ABORT_UNLESS(flag);
- heap.pop();
- flag = false;
-
- TInstant& nextDeadline = family.*FamilyToNextDeadline;
- if (now < nextDeadline) {
- deadline = nextDeadline;
- heap.push(it);
- flag = true;
- continue;
- }
-
- // Remove unnecessary items
- if (!it->second.Needed()) {
- NameToState.erase(it);
- if (MonCounters) {
- *MonCounters->CacheSize = NameToState.size();
- }
- }
- }
- }
-
- void CleanupExpired(TInstant now) {
- DoCleanupExpired<&TState::StateUnspec, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapUnspec, now);
- DoCleanupExpired<&TState::StateUnspec, &TFamilyState::HardDeadline, &TFamilyState::NextHardDeadline, &TFamilyState::InHardHeap>(HardHeapUnspec, now);
- DoCleanupExpired<&TState::StateIPv6, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapIPv6, now);
- DoCleanupExpired<&TState::StateIPv6, &TFamilyState::HardDeadline, &TFamilyState::NextHardDeadline, &TFamilyState::InHardHeap>(HardHeapIPv6, now);
- DoCleanupExpired<&TState::StateIPv4, &TFamilyState::SoftDeadline, &TFamilyState::NextSoftDeadline, &TFamilyState::InSoftHeap>(SoftHeapIPv4, now);
- DoCleanupExpired<&TState::StateIPv4, &TFamilyState::HardDeadline, &TFamilyState::NextHardDeadline, &TFamilyState::InHardHeap>(HardHeapIPv4, now);
- }
-
- template<class TEvent>
- void SendError(TActorId replyTo, ui64 cookie, int status, const TString& errorText) {
- auto reply = MakeHolder<TEvent>();
- reply->Status = status;
- reply->ErrorText = errorText;
- this->Send(replyTo, reply.Release(), 0, cookie);
- }
-
- void ReplyWithError(THolder<TIncomingRequest> req, int status, const TString& errorText) {
- if (MonCounters) {
- ++*MonCounters->IncomingErrors;
- }
- switch (req->Type) {
- case EIncomingRequestType::GetHostByName: {
- SendError<TEvDns::TEvGetHostByNameResult>(req->Sender, req->Cookie, status, errorText);
- break;
- }
- case EIncomingRequestType::GetAddr: {
- SendError<TEvDns::TEvGetAddrResult>(req->Sender, req->Cookie, status, errorText);
- break;
- }
- }
- }
-
- void ReplyWithAddrs(THolder<TIncomingRequest> req, const TVector<struct in6_addr>& addrs6, const TVector<struct in_addr>& addrs4) {
- switch (req->Type) {
- case EIncomingRequestType::GetHostByName: {
- auto reply = MakeHolder<TEvDns::TEvGetHostByNameResult>();
- reply->AddrsV6 = addrs6;
- reply->AddrsV4 = addrs4;
- Send(req->Sender, reply.Release(), 0, req->Cookie);
- break;
- }
- case EIncomingRequestType::GetAddr: {
- auto reply = MakeHolder<TEvDns::TEvGetAddrResult>();
- if (!addrs6.empty()) {
- reply->Addr = addrs6.front();
- } else if (!addrs4.empty()) {
- reply->Addr = addrs4.front();
- } else {
- Y_ABORT("Unexpected reply with empty address list");
- }
- Send(req->Sender, reply.Release(), 0, req->Cookie);
- break;
- }
- }
- }
-
- void ReplyWithError(THolder<TIncomingRequest> req, int status) {
- ReplyWithError(std::move(req), status, ares_strerror(status));
- }
-
- void DropPending(TIncomingRequestList& list, int status, const TString& errorText) {
- while (list) {
- THolder<TIncomingRequest> req(list.PopFront());
- ReplyWithError(std::move(req), status, errorText);
- }
- }
-
- void DropPending(int status, const TString& errorText) {
- for (auto& [name, state] : NameToState) {
- DropPending(state.StateUnspec.WaitingRequests, status, errorText);
- DropPending(state.StateIPv6.WaitingRequests, status, errorText);
- DropPending(state.StateIPv4.WaitingRequests, status, errorText);
- }
- }
-
- void DropPending(int status) {
- DropPending(status, ares_strerror(status));
- }
-
- private:
- const TActorId Upstream;
- const TCachingDnsResolverOptions Options;
- const THolder<TMonCounters> MonCounters;
-
- TNameToState NameToState;
- TStateHeap<&TState::StateUnspec, &TFamilyState::SoftDeadline> SoftHeapUnspec;
- TStateHeap<&TState::StateUnspec, &TFamilyState::HardDeadline> HardHeapUnspec;
- TStateHeap<&TState::StateIPv6, &TFamilyState::SoftDeadline> SoftHeapIPv6;
- TStateHeap<&TState::StateIPv6, &TFamilyState::HardDeadline> HardHeapIPv6;
- TStateHeap<&TState::StateIPv4, &TFamilyState::SoftDeadline> SoftHeapIPv4;
- TStateHeap<&TState::StateIPv4, &TFamilyState::HardDeadline> HardHeapIPv4;
-
- THashMap<ui64, TWaitingInfo> WaitingRequests;
- ui64 LastRequestId = 0;
- };
-
- IActor* CreateCachingDnsResolver(TActorId upstream, TCachingDnsResolverOptions options) {
- return new TCachingDnsResolver(upstream, std::move(options));
- }
-
-} // namespace NDnsResolver
-} // namespace NActors
diff --git a/library/cpp/actors/dnsresolver/dnsresolver_caching_ut.cpp b/library/cpp/actors/dnsresolver/dnsresolver_caching_ut.cpp
deleted file mode 100644
index 60a45f6fba..0000000000
--- a/library/cpp/actors/dnsresolver/dnsresolver_caching_ut.cpp
+++ /dev/null
@@ -1,648 +0,0 @@
-#include "dnsresolver.h"
-
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/testlib/test_runtime.h>
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/string/builder.h>
-
-#include <ares.h>
-
-using namespace NActors;
-using namespace NActors::NDnsResolver;
-
-// FIXME: use a mock resolver
-Y_UNIT_TEST_SUITE(CachingDnsResolver) {
-
- struct TAddrToString {
- TString operator()(const std::monostate&) const {
- return "<nothing>";
- }
-
- TString operator()(const struct in6_addr& addr) const {
- char dst[INET6_ADDRSTRLEN];
- auto res = ares_inet_ntop(AF_INET6, &addr, dst, INET6_ADDRSTRLEN);
- Y_ABORT_UNLESS(res, "Cannot convert ipv6 address");
- return dst;
- }
-
- TString operator()(const struct in_addr& addr) const {
- char dst[INET_ADDRSTRLEN];
- auto res = ares_inet_ntop(AF_INET, &addr, dst, INET_ADDRSTRLEN);
- Y_ABORT_UNLESS(res, "Cannot convert ipv4 address");
- return dst;
- }
- };
-
- TString AddrToString(const std::variant<std::monostate, struct in6_addr, struct in_addr>& v) {
- return std::visit(TAddrToString(), v);
- }
-
- struct TMockReply {
- static constexpr TDuration DefaultDelay = TDuration::MilliSeconds(1);
-
- int Status = 0;
- TDuration Delay;
- TVector<struct in6_addr> AddrsV6;
- TVector<struct in_addr> AddrsV4;
-
- static TMockReply Error(int status, TDuration delay = DefaultDelay) {
- Y_ABORT_UNLESS(status != 0);
- TMockReply reply;
- reply.Status = status;
- reply.Delay = delay;
- return reply;
- }
-
- static TMockReply Empty(TDuration delay = DefaultDelay) {
- TMockReply reply;
- reply.Delay = delay;
- return reply;
- }
-
- static TMockReply ManyV6(const TVector<TString>& addrs, TDuration delay = DefaultDelay) {
- TMockReply reply;
- reply.Delay = delay;
- for (const TString& addr : addrs) {
- void* dst = &reply.AddrsV6.emplace_back();
- int status = ares_inet_pton(AF_INET6, addr.c_str(), dst);
- Y_ABORT_UNLESS(status == 1, "Invalid ipv6 address: %s", addr.c_str());
- }
- return reply;
- }
-
- static TMockReply ManyV4(const TVector<TString>& addrs, TDuration delay = DefaultDelay) {
- TMockReply reply;
- reply.Delay = delay;
- for (const TString& addr : addrs) {
- void* dst = &reply.AddrsV4.emplace_back();
- int status = ares_inet_pton(AF_INET, addr.c_str(), dst);
- Y_ABORT_UNLESS(status == 1, "Invalid ipv4 address: %s", addr.c_str());
- }
- return reply;
- }
-
- static TMockReply SingleV6(const TString& addr, TDuration delay = DefaultDelay) {
- return ManyV6({ addr }, delay);
- }
-
- static TMockReply SingleV4(const TString& addr, TDuration delay = DefaultDelay) {
- return ManyV4({ addr }, delay);
- }
-
- friend TMockReply operator+(const TMockReply& a, const TMockReply& b) {
- Y_ABORT_UNLESS(a.Status == b.Status);
- TMockReply result;
- result.Status = a.Status;
- result.Delay = Max(a.Delay, b.Delay);
- result.AddrsV6.insert(result.AddrsV6.end(), a.AddrsV6.begin(), a.AddrsV6.end());
- result.AddrsV6.insert(result.AddrsV6.end(), b.AddrsV6.begin(), b.AddrsV6.end());
- result.AddrsV4.insert(result.AddrsV4.end(), a.AddrsV4.begin(), a.AddrsV4.end());
- result.AddrsV4.insert(result.AddrsV4.end(), b.AddrsV4.begin(), b.AddrsV4.end());
- return result;
- }
- };
-
- using TMockDnsCallback = std::function<TMockReply (const TString&, int)>;
-
- class TMockDnsResolver : public TActor<TMockDnsResolver> {
- public:
- TMockDnsResolver(TMockDnsCallback callback)
- : TActor(&TThis::StateWork)
- , Callback(std::move(callback))
- { }
-
- private:
- struct TEvPrivate {
- enum EEv {
- EvScheduled = EventSpaceBegin(TEvents::ES_PRIVATE),
- };
-
- struct TEvScheduled : public TEventLocal<TEvScheduled, EvScheduled> {
- TActorId Sender;
- ui64 Cookie;
- TMockReply Reply;
-
- TEvScheduled(TActorId sender, ui64 cookie, TMockReply reply)
- : Sender(sender)
- , Cookie(cookie)
- , Reply(std::move(reply))
- { }
- };
- };
-
- private:
- STRICT_STFUNC(StateWork, {
- hFunc(TEvents::TEvPoison, Handle);
- hFunc(TEvDns::TEvGetHostByName, Handle);
- hFunc(TEvPrivate::TEvScheduled, Handle);
- });
-
- void Handle(TEvents::TEvPoison::TPtr&) {
- PassAway();
- }
-
- void Handle(TEvDns::TEvGetHostByName::TPtr& ev) {
- auto reply = Callback(ev->Get()->Name, ev->Get()->Family);
- if (reply.Delay) {
- Schedule(reply.Delay, new TEvPrivate::TEvScheduled(ev->Sender, ev->Cookie, std::move(reply)));
- } else {
- SendReply(ev->Sender, ev->Cookie, std::move(reply));
- }
- }
-
- void Handle(TEvPrivate::TEvScheduled::TPtr& ev) {
- SendReply(ev->Get()->Sender, ev->Get()->Cookie, std::move(ev->Get()->Reply));
- }
-
- private:
- void SendReply(const TActorId& sender, ui64 cookie, TMockReply&& reply) {
- auto res = MakeHolder<TEvDns::TEvGetHostByNameResult>();
- res->Status = reply.Status;
- if (res->Status != 0) {
- res->ErrorText = ares_strerror(res->Status);
- } else {
- res->AddrsV6 = std::move(reply.AddrsV6);
- res->AddrsV4 = std::move(reply.AddrsV4);
- }
- Send(sender, res.Release(), 0, cookie);
- }
-
- private:
- TMockDnsCallback Callback;
- };
-
- struct TCachingDnsRuntime : public TTestActorRuntimeBase {
- TCachingDnsResolverOptions ResolverOptions;
- TActorId MockResolver;
- TActorId Resolver;
- TActorId Sleeper;
- TString Section_;
-
- NMonitoring::TDynamicCounters::TCounterPtr InFlightUnspec;
- NMonitoring::TDynamicCounters::TCounterPtr InFlight6;
- NMonitoring::TDynamicCounters::TCounterPtr InFlight4;
- NMonitoring::TDynamicCounters::TCounterPtr TotalUnspec;
- NMonitoring::TDynamicCounters::TCounterPtr Total6;
- NMonitoring::TDynamicCounters::TCounterPtr Total4;
- NMonitoring::TDynamicCounters::TCounterPtr Misses;
- NMonitoring::TDynamicCounters::TCounterPtr Hits;
-
- THashMap<TString, TMockReply> ReplyV6;
- THashMap<TString, TMockReply> ReplyV4;
- THashMap<TString, TMockReply> ReplyUnspec;
-
- TCachingDnsRuntime() {
- SetScheduledEventFilter([](auto&&, auto&&, auto&&, auto&&) { return false; });
- ResolverOptions.MonCounters = new NMonitoring::TDynamicCounters;
-
- ReplyV6["localhost"] = TMockReply::SingleV6("::1");
- ReplyV4["localhost"] = TMockReply::SingleV4("127.0.0.1");
- ReplyV6["yandex.ru"] = TMockReply::SingleV6("2a02:6b8:a::a", TDuration::MilliSeconds(500));
- ReplyV4["yandex.ru"] = TMockReply::SingleV4("77.88.55.77", TDuration::MilliSeconds(250));
- ReplyV6["router.asus.com"] = TMockReply::Error(ARES_ENODATA);
- ReplyV4["router.asus.com"] = TMockReply::SingleV4("192.168.0.1");
- ReplyUnspec["localhost"] = ReplyV6.at("localhost") + ReplyV4.at("localhost");
- ReplyUnspec["yandex.ru"] = ReplyV6.at("yandex.ru") + ReplyV4.at("yandex.ru");
- ReplyUnspec["router.asus.com"] = ReplyV4.at("router.asus.com");
- }
-
- void Start(TMockDnsCallback callback) {
- MockResolver = Register(new TMockDnsResolver(std::move(callback)));
- EnableScheduleForActor(MockResolver);
- Resolver = Register(CreateCachingDnsResolver(MockResolver, ResolverOptions));
- Sleeper = AllocateEdgeActor();
-
- InFlightUnspec = ResolverOptions.MonCounters->GetCounter("DnsResolver/Outgoing/InFlight/Unspec", false);
- InFlight6 = ResolverOptions.MonCounters->GetCounter("DnsResolver/Outgoing/InFlight/V6", false);
- InFlight4 = ResolverOptions.MonCounters->GetCounter("DnsResolver/Outgoing/InFlight/V4", false);
- TotalUnspec = ResolverOptions.MonCounters->GetCounter("DnsResolver/Outgoing/Total/Unspec", true);
- Total6 = ResolverOptions.MonCounters->GetCounter("DnsResolver/Outgoing/Total/V6", true);
- Total4 = ResolverOptions.MonCounters->GetCounter("DnsResolver/Outgoing/Total/V4", true);
- Misses = ResolverOptions.MonCounters->GetCounter("DnsResolver/Cache/Misses", true);
- Hits = ResolverOptions.MonCounters->GetCounter("DnsResolver/Cache/Hits", true);
- }
-
- void Start() {
- Start([this](const TString& name, int family) {
- switch (family) {
- case AF_UNSPEC: {
- auto it = ReplyUnspec.find(name);
- if (it != ReplyUnspec.end()) {
- return it->second;
- }
- break;
- }
- case AF_INET6: {
- auto it = ReplyV6.find(name);
- if (it != ReplyV6.end()) {
- return it->second;
- }
- break;
- }
- case AF_INET: {
- auto it = ReplyV4.find(name);
- if (it != ReplyV4.end()) {
- return it->second;
- }
- break;
- }
- }
- return TMockReply::Error(ARES_ENOTFOUND);
- });
- }
-
- void Section(const TString& section) {
- Section_ = section;
- }
-
- void Sleep(TDuration duration) {
- Schedule(new IEventHandle(Sleeper, Sleeper, new TEvents::TEvWakeup), duration);
- GrabEdgeEventRethrow<TEvents::TEvWakeup>(Sleeper);
- }
-
- void WaitNoInFlight() {
- if (*InFlightUnspec || *InFlight6 || *InFlight4) {
- TDispatchOptions options;
- options.CustomFinalCondition = [&]() {
- return !*InFlightUnspec && !*InFlight6 && !*InFlight4;
- };
- DispatchEvents(options);
- UNIT_ASSERT_C(!*InFlight6 && !*InFlight4, "Failed to wait for no inflight in " << Section_);
- }
- }
-
- void SendGetHostByName(const TActorId& sender, const TString& name, int family = AF_UNSPEC) {
- Send(new IEventHandle(Resolver, sender, new TEvDns::TEvGetHostByName(name, family)), 0, true);
- }
-
- void SendGetAddr(const TActorId& sender, const TString& name, int family = AF_UNSPEC) {
- Send(new IEventHandle(Resolver, sender, new TEvDns::TEvGetAddr(name, family)), 0, true);
- }
-
- TEvDns::TEvGetHostByNameResult::TPtr WaitGetHostByName(const TActorId& sender) {
- return GrabEdgeEventRethrow<TEvDns::TEvGetHostByNameResult>(sender);
- }
-
- TEvDns::TEvGetAddrResult::TPtr WaitGetAddr(const TActorId& sender) {
- return GrabEdgeEventRethrow<TEvDns::TEvGetAddrResult>(sender);
- }
-
- void ExpectInFlightUnspec(i64 count) {
- UNIT_ASSERT_VALUES_EQUAL_C(InFlightUnspec->Val(), count, Section_);
- }
-
- void ExpectInFlight6(i64 count) {
- UNIT_ASSERT_VALUES_EQUAL_C(InFlight6->Val(), count, Section_);
- }
-
- void ExpectInFlight4(i64 count) {
- UNIT_ASSERT_VALUES_EQUAL_C(InFlight4->Val(), count, Section_);
- }
-
- void ExpectTotalUnspec(i64 count) {
- UNIT_ASSERT_VALUES_EQUAL_C(TotalUnspec->Val(), count, Section_);
- }
-
- void ExpectTotal6(i64 count) {
- UNIT_ASSERT_VALUES_EQUAL_C(Total6->Val(), count, Section_);
- }
-
- void ExpectTotal4(i64 count) {
- UNIT_ASSERT_VALUES_EQUAL_C(Total4->Val(), count, Section_);
- }
-
- void ExpectUnspec(i64 total, i64 inflight) {
- UNIT_ASSERT_C(
- TotalUnspec->Val() == total && InFlightUnspec->Val() == inflight,
- Section_ << ": Expect6(" << total << ", " << inflight << ") "
- << " but got (" << TotalUnspec->Val() << ", " << InFlightUnspec->Val() << ")");
- }
-
- void Expect6(i64 total, i64 inflight) {
- UNIT_ASSERT_C(
- Total6->Val() == total && InFlight6->Val() == inflight,
- Section_ << ": Expect6(" << total << ", " << inflight << ") "
- << " but got (" << Total6->Val() << ", " << InFlight6->Val() << ")");
- }
-
- void Expect4(i64 total, i64 inflight) {
- UNIT_ASSERT_C(
- Total4->Val() == total && InFlight4->Val() == inflight,
- Section_ << ": Expect4(" << total << ", " << inflight << ") "
- << " got (" << Total4->Val() << ", " << InFlight4->Val() << ")");
- }
-
- void ExpectMisses(i64 count) {
- UNIT_ASSERT_VALUES_EQUAL_C(Misses->Val(), count, Section_);
- }
-
- void ExpectHits(i64 count) {
- UNIT_ASSERT_VALUES_EQUAL_C(Hits->Val(), count, Section_);
- }
-
- void ExpectGetHostByNameError(const TActorId& sender, int status) {
- auto ev = WaitGetHostByName(sender);
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, status, Section_ << ": " << ev->Get()->ErrorText);
- }
-
- void ExpectGetAddrError(const TActorId& sender, int status) {
- auto ev = WaitGetAddr(sender);
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, status, Section_ << ": " << ev->Get()->ErrorText);
- }
-
- void ExpectGetHostByNameSuccess(const TActorId& sender, const TString& expected) {
- auto ev = WaitGetHostByName(sender);
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, 0, Section_ << ": " << ev->Get()->ErrorText);
- TStringBuilder result;
- for (const auto& addr : ev->Get()->AddrsV6) {
- if (result) {
- result << ',';
- }
- result << TAddrToString()(addr);
- }
- for (const auto& addr : ev->Get()->AddrsV4) {
- if (result) {
- result << ',';
- }
- result << TAddrToString()(addr);
- }
- UNIT_ASSERT_VALUES_EQUAL_C(TString(result), expected, Section_);
- }
-
- void ExpectGetAddrSuccess(const TActorId& sender, const TString& expected) {
- auto ev = WaitGetAddr(sender);
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, 0, Section_ << ": " << ev->Get()->ErrorText);
- TString result = AddrToString(ev->Get()->Addr);
- UNIT_ASSERT_VALUES_EQUAL_C(result, expected, Section_);
- }
- };
-
- Y_UNIT_TEST(UnusableResolver) {
- TCachingDnsRuntime runtime;
- runtime.Initialize();
- runtime.Start();
-
- auto sender = runtime.AllocateEdgeActor();
-
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "2a02:6b8:a::a");
-
- runtime.Send(new IEventHandle(runtime.MockResolver, { }, new TEvents::TEvPoison), 0, true);
- runtime.SendGetAddr(sender, "foo.ru", AF_UNSPEC);
- runtime.ExpectGetAddrError(sender, ARES_ENOTINITIALIZED);
- }
-
- Y_UNIT_TEST(ResolveCaching) {
- TCachingDnsRuntime runtime;
- runtime.Initialize();
- runtime.Start();
-
- auto sender = runtime.AllocateEdgeActor();
-
- // First time resolve, we expect AF_UNSPEC result to be cached
- runtime.Section("First time resolve");
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "2a02:6b8:a::a");
- runtime.ExpectUnspec(1, 0);
- runtime.ExpectMisses(1);
- runtime.ExpectHits(0);
-
- // Second resolve, unspec is a cache hit, ipv6 and ipv4 result in cache misses
- runtime.Section("Second resolve");
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "2a02:6b8:a::a");
- runtime.ExpectUnspec(1, 0);
- runtime.ExpectHits(1);
-
- // Wait until soft expiration and try unspec again
- // Will cause a cache hit, but will start a new request in background
- runtime.Section("Retry both after soft expiration");
- runtime.Sleep(TDuration::Seconds(15));
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "2a02:6b8:a::a");
- runtime.ExpectUnspec(2, 1);
- runtime.ExpectMisses(1);
- runtime.ExpectHits(2);
- runtime.WaitNoInFlight();
-
- // Wait until hard expiration and try unspec again
- // Will cause a cache miss and new resolve requests
- runtime.Section("Retry both after hard expiration");
- runtime.Sleep(TDuration::Hours(2));
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "2a02:6b8:a::a");
- runtime.ExpectUnspec(3, 0);
- runtime.ExpectMisses(2);
- runtime.ExpectHits(2);
-
- // Wait half the hard expiration time, must always result in a cache hit
- runtime.Section("Retry both after half hard expiration");
- for (ui64 i = 1; i <= 4; ++i) {
- runtime.Sleep(TDuration::Hours(1));
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "2a02:6b8:a::a");
- runtime.ExpectUnspec(3 + i, 1);
- runtime.ExpectHits(2 + i);
- runtime.WaitNoInFlight();
- }
-
- // Change unspec result to a timeout, must keep using cached result until hard expiration
- runtime.Section("Dns keeps timing out");
- runtime.ReplyUnspec["yandex.ru"] = TMockReply::Error(ARES_ETIMEOUT);
- for (ui64 i = 1; i <= 4; ++i) {
- runtime.Sleep(TDuration::Seconds(15));
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "2a02:6b8:a::a");
- runtime.ExpectUnspec(7 + i, 1);
- runtime.ExpectHits(6 + i);
- runtime.WaitNoInFlight();
- }
-
- // Change unspec result to v4, must switch to a v4 result eventually
- runtime.Section("Host changes to being ipv4 only");
- runtime.ReplyUnspec["yandex.ru"] = runtime.ReplyV4.at("yandex.ru");
- runtime.Sleep(TDuration::Seconds(2));
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "2a02:6b8:a::a");
- runtime.WaitNoInFlight();
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "77.88.55.77");
- runtime.ExpectUnspec(12, 0);
- runtime.ExpectMisses(2);
-
- // Change unspec result to nxdomain, must start returning it
- runtime.Section("Host is removed from dns");
- runtime.ReplyUnspec["yandex.ru"] = TMockReply::Error(ARES_ENOTFOUND);
- runtime.Sleep(TDuration::Seconds(15));
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "77.88.55.77");
- runtime.WaitNoInFlight();
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetAddrError(sender, ARES_ENOTFOUND);
- }
-
- Y_UNIT_TEST(ResolveCachingV4) {
- TCachingDnsRuntime runtime;
- runtime.Initialize();
- runtime.Start();
-
- auto sender = runtime.AllocateEdgeActor();
-
- runtime.Section("First request");
- runtime.SendGetAddr(sender, "router.asus.com", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "192.168.0.1");
- runtime.ExpectMisses(1);
-
- runtime.Section("Second request");
- runtime.SendGetAddr(sender, "router.asus.com", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "192.168.0.1");
- runtime.ExpectHits(1);
-
- runtime.Section("Dns keeps timing out");
- runtime.ReplyUnspec["router.asus.com"] = TMockReply::Error(ARES_ETIMEOUT);
- for (ui64 i = 1; i <= 4; ++i) {
- runtime.Sleep(TDuration::Seconds(15));
- runtime.SendGetAddr(sender, "router.asus.com", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "192.168.0.1");
- runtime.ExpectUnspec(1 + i, 1);
- runtime.ExpectHits(1 + i);
- runtime.WaitNoInFlight();
- }
-
- runtime.Section("Host is removed from dns");
- runtime.ReplyUnspec["router.asus.com"] = TMockReply::Error(ARES_ENOTFOUND);
- runtime.Sleep(TDuration::Seconds(15));
- runtime.SendGetAddr(sender, "router.asus.com", AF_UNSPEC);
- runtime.ExpectGetAddrSuccess(sender, "192.168.0.1");
- runtime.WaitNoInFlight();
- runtime.SendGetAddr(sender, "router.asus.com", AF_UNSPEC);
- runtime.ExpectGetAddrError(sender, ARES_ENOTFOUND);
- }
-
- Y_UNIT_TEST(EventualTimeout) {
- TCachingDnsRuntime runtime;
- runtime.Initialize();
- runtime.Start();
-
- auto sender = runtime.AllocateEdgeActor();
-
- runtime.ReplyUnspec["notfound.ru"] = TMockReply::Error(ARES_ENOTFOUND);
- runtime.SendGetAddr(sender, "notfound.ru", AF_UNSPEC);
- runtime.ExpectGetAddrError(sender, ARES_ENOTFOUND);
-
- runtime.ReplyUnspec["notfound.ru"] = TMockReply::Error(ARES_ETIMEOUT);
- runtime.SendGetAddr(sender, "notfound.ru", AF_UNSPEC);
- runtime.ExpectGetAddrError(sender, ARES_ENOTFOUND);
- runtime.WaitNoInFlight();
-
- bool timeout = false;
- for (ui64 i = 1; i <= 8; ++i) {
- runtime.Sleep(TDuration::Minutes(30));
- runtime.SendGetAddr(sender, "notfound.ru", AF_UNSPEC);
- auto ev = runtime.WaitGetAddr(sender);
- if (ev->Get()->Status == ARES_ETIMEOUT && i > 2) {
- timeout = true;
- break;
- }
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, ARES_ENOTFOUND,
- "Iteration " << i << ": " << ev->Get()->ErrorText);
- }
-
- UNIT_ASSERT_C(timeout, "DnsResolver did not reply with a timeout");
- }
-
- Y_UNIT_TEST(MultipleRequestsAndHosts) {
- TCachingDnsRuntime runtime;
- runtime.Initialize();
- runtime.Start();
-
- auto sender = runtime.AllocateEdgeActor();
-
- runtime.SendGetHostByName(sender, "router.asus.com", AF_UNSPEC);
- runtime.SendGetAddr(sender, "router.asus.com", AF_UNSPEC);
- runtime.SendGetHostByName(sender, "yandex.ru", AF_UNSPEC);
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetHostByNameSuccess(sender, "192.168.0.1");
- runtime.ExpectGetAddrSuccess(sender, "192.168.0.1");
- runtime.ExpectGetHostByNameSuccess(sender, "2a02:6b8:a::a,77.88.55.77");
- runtime.ExpectGetAddrSuccess(sender, "2a02:6b8:a::a");
-
- runtime.SendGetHostByName(sender, "notfound.ru", AF_UNSPEC);
- runtime.SendGetAddr(sender, "notfound.ru", AF_UNSPEC);
- runtime.ExpectGetHostByNameError(sender, ARES_ENOTFOUND);
- runtime.ExpectGetAddrError(sender, ARES_ENOTFOUND);
- }
-
- Y_UNIT_TEST(DisabledIPv6) {
- TCachingDnsRuntime runtime;
- runtime.ResolverOptions.AllowIPv6 = false;
- runtime.Initialize();
- runtime.Start();
-
- auto sender = runtime.AllocateEdgeActor();
-
- runtime.SendGetHostByName(sender, "yandex.ru", AF_UNSPEC);
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetHostByNameSuccess(sender, "77.88.55.77");
- runtime.ExpectGetAddrSuccess(sender, "77.88.55.77");
-
- runtime.SendGetHostByName(sender, "yandex.ru", AF_INET6);
- runtime.SendGetAddr(sender, "yandex.ru", AF_INET6);
- runtime.ExpectGetHostByNameError(sender, ARES_EBADFAMILY);
- runtime.ExpectGetAddrError(sender, ARES_EBADFAMILY);
-
- runtime.SendGetHostByName(sender, "yandex.ru", AF_UNSPEC);
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.ExpectGetHostByNameSuccess(sender, "77.88.55.77");
- runtime.ExpectGetAddrSuccess(sender, "77.88.55.77");
-
- runtime.SendGetHostByName(sender, "notfound.ru", AF_UNSPEC);
- runtime.SendGetAddr(sender, "notfound.ru", AF_UNSPEC);
- runtime.ExpectGetHostByNameError(sender, ARES_ENOTFOUND);
- runtime.ExpectGetAddrError(sender, ARES_ENOTFOUND);
- }
-
- Y_UNIT_TEST(DisabledIPv4) {
- TCachingDnsRuntime runtime;
- runtime.ResolverOptions.AllowIPv4 = false;
- runtime.Initialize();
- runtime.Start();
-
- auto sender = runtime.AllocateEdgeActor();
-
- runtime.SendGetHostByName(sender, "router.asus.com", AF_UNSPEC);
- runtime.SendGetAddr(sender, "router.asus.com", AF_UNSPEC);
- runtime.ExpectGetHostByNameError(sender, ARES_ENODATA);
- runtime.ExpectGetAddrError(sender, ARES_ENODATA);
-
- runtime.SendGetHostByName(sender, "router.asus.com", AF_INET);
- runtime.SendGetAddr(sender, "router.asus.com", AF_INET);
- runtime.ExpectGetHostByNameError(sender, ARES_EBADFAMILY);
- runtime.ExpectGetAddrError(sender, ARES_EBADFAMILY);
-
- runtime.SendGetHostByName(sender, "router.asus.com", AF_UNSPEC);
- runtime.SendGetAddr(sender, "router.asus.com", AF_UNSPEC);
- runtime.ExpectGetHostByNameError(sender, ARES_ENODATA);
- runtime.ExpectGetAddrError(sender, ARES_ENODATA);
-
- runtime.SendGetHostByName(sender, "notfound.ru", AF_UNSPEC);
- runtime.SendGetAddr(sender, "notfound.ru", AF_UNSPEC);
- runtime.ExpectGetHostByNameError(sender, ARES_ENOTFOUND);
- runtime.ExpectGetAddrError(sender, ARES_ENOTFOUND);
- }
-
- Y_UNIT_TEST(PoisonPill) {
- TCachingDnsRuntime runtime;
- runtime.Initialize();
- runtime.Start();
-
- auto sender = runtime.AllocateEdgeActor();
-
- runtime.SendGetHostByName(sender, "yandex.ru", AF_UNSPEC);
- runtime.SendGetAddr(sender, "yandex.ru", AF_UNSPEC);
- runtime.Send(new IEventHandle(runtime.Resolver, sender, new TEvents::TEvPoison), 0, true);
- runtime.ExpectGetHostByNameError(sender, ARES_ECANCELLED);
- runtime.ExpectGetAddrError(sender, ARES_ECANCELLED);
- }
-
-}
diff --git a/library/cpp/actors/dnsresolver/dnsresolver_ondemand.cpp b/library/cpp/actors/dnsresolver/dnsresolver_ondemand.cpp
deleted file mode 100644
index 8b0ddf5a6d..0000000000
--- a/library/cpp/actors/dnsresolver/dnsresolver_ondemand.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "dnsresolver.h"
-
-#include <library/cpp/actors/core/hfunc.h>
-
-namespace NActors {
-namespace NDnsResolver {
-
- class TOnDemandDnsResolver : public TActor<TOnDemandDnsResolver> {
- public:
- TOnDemandDnsResolver(TOnDemandDnsResolverOptions options)
- : TActor(&TThis::StateWork)
- , Options(std::move(options))
- { }
-
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::DNS_RESOLVER;
- }
-
- private:
- STRICT_STFUNC(StateWork, {
- cFunc(TEvents::TEvPoison::EventType, PassAway);
- fFunc(TEvDns::TEvGetHostByName::EventType, Forward);
- fFunc(TEvDns::TEvGetAddr::EventType, Forward);
- });
-
- void Forward(STATEFN_SIG) {
- ev->Rewrite(ev->GetTypeRewrite(), GetUpstream());
- TActivationContext::Send(ev.Release());
- }
-
- private:
- TActorId GetUpstream() {
- if (Y_UNLIKELY(!CachingResolverId)) {
- if (Y_LIKELY(!SimpleResolverId)) {
- SimpleResolverId = RegisterWithSameMailbox(CreateSimpleDnsResolver(Options));
- }
- CachingResolverId = RegisterWithSameMailbox(CreateCachingDnsResolver(SimpleResolverId, Options));
- }
- return CachingResolverId;
- }
-
- void PassAway() override {
- if (CachingResolverId) {
- Send(CachingResolverId, new TEvents::TEvPoison);
- CachingResolverId = { };
- }
- if (SimpleResolverId) {
- Send(SimpleResolverId, new TEvents::TEvPoison);
- SimpleResolverId = { };
- }
- }
-
- private:
- TOnDemandDnsResolverOptions Options;
- TActorId SimpleResolverId;
- TActorId CachingResolverId;
- };
-
- IActor* CreateOnDemandDnsResolver(TOnDemandDnsResolverOptions options) {
- return new TOnDemandDnsResolver(std::move(options));
- }
-
-} // namespace NDnsResolver
-} // namespace NActors
diff --git a/library/cpp/actors/dnsresolver/dnsresolver_ondemand_ut.cpp b/library/cpp/actors/dnsresolver/dnsresolver_ondemand_ut.cpp
deleted file mode 100644
index 2758484552..0000000000
--- a/library/cpp/actors/dnsresolver/dnsresolver_ondemand_ut.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "dnsresolver.h"
-
-#include <library/cpp/actors/testlib/test_runtime.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NActors;
-using namespace NActors::NDnsResolver;
-
-Y_UNIT_TEST_SUITE(OnDemandDnsResolver) {
-
- Y_UNIT_TEST(ResolveLocalHost) {
- TTestActorRuntimeBase runtime;
- runtime.Initialize();
- auto sender = runtime.AllocateEdgeActor();
- auto resolver = runtime.Register(CreateOnDemandDnsResolver());
- runtime.Send(new IEventHandle(resolver, sender, new TEvDns::TEvGetHostByName("localhost", AF_UNSPEC)),
- 0, true);
- auto ev = runtime.GrabEdgeEventRethrow<TEvDns::TEvGetHostByNameResult>(sender);
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, 0, ev->Get()->ErrorText);
- size_t addrs = ev->Get()->AddrsV4.size() + ev->Get()->AddrsV6.size();
- UNIT_ASSERT_C(addrs > 0, "Got " << addrs << " addresses");
- }
-
-}
diff --git a/library/cpp/actors/dnsresolver/dnsresolver_ut.cpp b/library/cpp/actors/dnsresolver/dnsresolver_ut.cpp
deleted file mode 100644
index 93c4b832e2..0000000000
--- a/library/cpp/actors/dnsresolver/dnsresolver_ut.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "dnsresolver.h"
-
-#include <library/cpp/actors/testlib/test_runtime.h>
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/string/builder.h>
-
-#include <ares.h>
-
-using namespace NActors;
-using namespace NActors::NDnsResolver;
-
-Y_UNIT_TEST_SUITE(DnsResolver) {
-
- struct TSilentUdpServer {
- TInetDgramSocket Socket;
- ui16 Port;
-
- TSilentUdpServer() {
- TSockAddrInet addr("127.0.0.1", 0);
- int err = Socket.Bind(&addr);
- Y_ABORT_UNLESS(err == 0, "Cannot bind a udp socket");
- Port = addr.GetPort();
- }
- };
-
- Y_UNIT_TEST(ResolveLocalHost) {
- TTestActorRuntimeBase runtime;
- runtime.Initialize();
- auto sender = runtime.AllocateEdgeActor();
- auto resolver = runtime.Register(CreateSimpleDnsResolver());
- runtime.Send(new IEventHandle(resolver, sender, new TEvDns::TEvGetHostByName("localhost", AF_UNSPEC)),
- 0, true);
- auto ev = runtime.GrabEdgeEventRethrow<TEvDns::TEvGetHostByNameResult>(sender);
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, 0, ev->Get()->ErrorText);
- size_t addrs = ev->Get()->AddrsV4.size() + ev->Get()->AddrsV6.size();
- UNIT_ASSERT_C(addrs > 0, "Got " << addrs << " addresses");
- }
-
- Y_UNIT_TEST(ResolveYandexRu) {
- TTestActorRuntimeBase runtime;
- runtime.Initialize();
- auto sender = runtime.AllocateEdgeActor();
- auto resolver = runtime.Register(CreateSimpleDnsResolver());
- runtime.Send(new IEventHandle(resolver, sender, new TEvDns::TEvGetHostByName("yandex.ru", AF_UNSPEC)),
- 0, true);
- auto ev = runtime.GrabEdgeEventRethrow<TEvDns::TEvGetHostByNameResult>(sender);
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, 0, ev->Get()->ErrorText);
- size_t addrs = ev->Get()->AddrsV4.size() + ev->Get()->AddrsV6.size();
- UNIT_ASSERT_C(addrs > 0, "Got " << addrs << " addresses");
- }
-
- Y_UNIT_TEST(GetAddrYandexRu) {
- TTestActorRuntimeBase runtime;
- runtime.Initialize();
- auto sender = runtime.AllocateEdgeActor();
- auto resolver = runtime.Register(CreateSimpleDnsResolver());
-
- runtime.Send(new IEventHandle(resolver, sender, new TEvDns::TEvGetAddr("yandex.ru", AF_UNSPEC)),
- 0, true);
- auto ev = runtime.GrabEdgeEventRethrow<TEvDns::TEvGetAddrResult>(sender);
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, 0, ev->Get()->ErrorText);
- UNIT_ASSERT_C(ev->Get()->IsV4() || ev->Get()->IsV6(), "Expect v4 or v6 address");
- }
-
- Y_UNIT_TEST(ResolveTimeout) {
- TSilentUdpServer server;
- TTestActorRuntimeBase runtime;
- runtime.Initialize();
- auto sender = runtime.AllocateEdgeActor();
- TSimpleDnsResolverOptions options;
- options.Timeout = TDuration::MilliSeconds(250);
- options.Attempts = 2;
- options.Servers.emplace_back(TStringBuilder() << "127.0.0.1:" << server.Port);
- auto resolver = runtime.Register(CreateSimpleDnsResolver(options));
- runtime.Send(new IEventHandle(resolver, sender, new TEvDns::TEvGetHostByName("timeout.yandex.ru", AF_INET)),
- 0, true);
- auto ev = runtime.GrabEdgeEventRethrow<TEvDns::TEvGetHostByNameResult>(sender);
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, ARES_ETIMEOUT, ev->Get()->ErrorText);
- }
-
- Y_UNIT_TEST(ResolveGracefulStop) {
- TSilentUdpServer server;
- TTestActorRuntimeBase runtime;
- runtime.Initialize();
- auto sender = runtime.AllocateEdgeActor();
- TSimpleDnsResolverOptions options;
- options.Timeout = TDuration::Seconds(5);
- options.Attempts = 5;
- options.Servers.emplace_back(TStringBuilder() << "127.0.0.1:" << server.Port);
- auto resolver = runtime.Register(CreateSimpleDnsResolver(options));
- runtime.Send(new IEventHandle(resolver, sender, new TEvDns::TEvGetHostByName("timeout.yandex.ru", AF_INET)),
- 0, true);
- runtime.Send(new IEventHandle(resolver, sender, new TEvents::TEvPoison), 0, true);
- auto ev = runtime.GrabEdgeEventRethrow<TEvDns::TEvGetHostByNameResult>(sender);
- UNIT_ASSERT_VALUES_EQUAL_C(ev->Get()->Status, ARES_ECANCELLED, ev->Get()->ErrorText);
- }
-
-}
diff --git a/library/cpp/actors/dnsresolver/ut/CMakeLists.darwin-arm64.txt b/library/cpp/actors/dnsresolver/ut/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 8874bee8e5..0000000000
--- a/library/cpp/actors/dnsresolver/ut/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-dnsresolver-ut)
-target_include_directories(library-cpp-actors-dnsresolver-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver
- ${CMAKE_SOURCE_DIR}/contrib/libs/c-ares/include
-)
-target_link_libraries(library-cpp-actors-dnsresolver-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-dnsresolver
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-dnsresolver-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-dnsresolver-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_caching_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ondemand_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-dnsresolver-ut
- TEST_TARGET
- library-cpp-actors-dnsresolver-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-dnsresolver-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-dnsresolver-ut)
diff --git a/library/cpp/actors/dnsresolver/ut/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/dnsresolver/ut/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 9e092bba80..0000000000
--- a/library/cpp/actors/dnsresolver/ut/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-dnsresolver-ut)
-target_include_directories(library-cpp-actors-dnsresolver-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver
- ${CMAKE_SOURCE_DIR}/contrib/libs/c-ares/include
-)
-target_link_libraries(library-cpp-actors-dnsresolver-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-dnsresolver
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-dnsresolver-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-dnsresolver-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_caching_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ondemand_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-dnsresolver-ut
- TEST_TARGET
- library-cpp-actors-dnsresolver-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-dnsresolver-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-dnsresolver-ut)
diff --git a/library/cpp/actors/dnsresolver/ut/CMakeLists.linux-aarch64.txt b/library/cpp/actors/dnsresolver/ut/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index c8eb27acd0..0000000000
--- a/library/cpp/actors/dnsresolver/ut/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-dnsresolver-ut)
-target_include_directories(library-cpp-actors-dnsresolver-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver
- ${CMAKE_SOURCE_DIR}/contrib/libs/c-ares/include
-)
-target_link_libraries(library-cpp-actors-dnsresolver-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-dnsresolver
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-dnsresolver-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-dnsresolver-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_caching_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ondemand_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-dnsresolver-ut
- TEST_TARGET
- library-cpp-actors-dnsresolver-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-dnsresolver-ut
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-dnsresolver-ut)
diff --git a/library/cpp/actors/dnsresolver/ut/CMakeLists.linux-x86_64.txt b/library/cpp/actors/dnsresolver/ut/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index eae7bc85a3..0000000000
--- a/library/cpp/actors/dnsresolver/ut/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-dnsresolver-ut)
-target_include_directories(library-cpp-actors-dnsresolver-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver
- ${CMAKE_SOURCE_DIR}/contrib/libs/c-ares/include
-)
-target_link_libraries(library-cpp-actors-dnsresolver-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-dnsresolver
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-dnsresolver-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-dnsresolver-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_caching_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ondemand_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-dnsresolver-ut
- TEST_TARGET
- library-cpp-actors-dnsresolver-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-dnsresolver-ut
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-dnsresolver-ut)
diff --git a/library/cpp/actors/dnsresolver/ut/CMakeLists.txt b/library/cpp/actors/dnsresolver/ut/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/dnsresolver/ut/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/dnsresolver/ut/CMakeLists.windows-x86_64.txt b/library/cpp/actors/dnsresolver/ut/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 7705d206a3..0000000000
--- a/library/cpp/actors/dnsresolver/ut/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-dnsresolver-ut)
-target_include_directories(library-cpp-actors-dnsresolver-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver
- ${CMAKE_SOURCE_DIR}/contrib/libs/c-ares/include
-)
-target_link_libraries(library-cpp-actors-dnsresolver-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-dnsresolver
- cpp-actors-testlib
-)
-target_sources(library-cpp-actors-dnsresolver-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_caching_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ondemand_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/dnsresolver/dnsresolver_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-dnsresolver-ut
- TEST_TARGET
- library-cpp-actors-dnsresolver-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-dnsresolver-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-dnsresolver-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-dnsresolver-ut)
diff --git a/library/cpp/actors/dnsresolver/ut/ya.make b/library/cpp/actors/dnsresolver/ut/ya.make
deleted file mode 100644
index ec4b117bf7..0000000000
--- a/library/cpp/actors/dnsresolver/ut/ya.make
+++ /dev/null
@@ -1,18 +0,0 @@
-UNITTEST_FOR(library/cpp/actors/dnsresolver)
-
-PEERDIR(
- library/cpp/actors/testlib
-)
-
-SRCS(
- dnsresolver_caching_ut.cpp
- dnsresolver_ondemand_ut.cpp
- dnsresolver_ut.cpp
-)
-
-ADDINCL(contrib/libs/c-ares/include)
-
-TAG(ya:external)
-REQUIREMENTS(network:full)
-
-END()
diff --git a/library/cpp/actors/dnsresolver/ya.make b/library/cpp/actors/dnsresolver/ya.make
deleted file mode 100644
index 6d9318a254..0000000000
--- a/library/cpp/actors/dnsresolver/ya.make
+++ /dev/null
@@ -1,18 +0,0 @@
-LIBRARY()
-
-SRCS(
- dnsresolver.cpp
- dnsresolver_caching.cpp
- dnsresolver_ondemand.cpp
-)
-
-PEERDIR(
- library/cpp/actors/core
- contrib/libs/c-ares
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- ut
-)
diff --git a/library/cpp/actors/examples/01_ping_pong/CMakeLists.darwin-arm64.txt b/library/cpp/actors/examples/01_ping_pong/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index b2acea01a5..0000000000
--- a/library/cpp/actors/examples/01_ping_pong/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(example_01_ping_pong)
-target_link_libraries(example_01_ping_pong PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
-)
-target_link_options(example_01_ping_pong PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(example_01_ping_pong PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/01_ping_pong/main.cpp
-)
-target_allocator(example_01_ping_pong
- library-cpp-lfalloc
-)
-vcs_info(example_01_ping_pong)
diff --git a/library/cpp/actors/examples/01_ping_pong/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/examples/01_ping_pong/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 1e053eb6b4..0000000000
--- a/library/cpp/actors/examples/01_ping_pong/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(example_01_ping_pong)
-target_link_libraries(example_01_ping_pong PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-actors-core
-)
-target_link_options(example_01_ping_pong PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(example_01_ping_pong PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/01_ping_pong/main.cpp
-)
-target_allocator(example_01_ping_pong
- library-cpp-lfalloc
-)
-vcs_info(example_01_ping_pong)
diff --git a/library/cpp/actors/examples/01_ping_pong/CMakeLists.linux-aarch64.txt b/library/cpp/actors/examples/01_ping_pong/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 5884f06261..0000000000
--- a/library/cpp/actors/examples/01_ping_pong/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(example_01_ping_pong)
-target_link_libraries(example_01_ping_pong PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
-)
-target_link_options(example_01_ping_pong PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(example_01_ping_pong PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/01_ping_pong/main.cpp
-)
-target_allocator(example_01_ping_pong
- library-cpp-lfalloc
-)
-vcs_info(example_01_ping_pong)
diff --git a/library/cpp/actors/examples/01_ping_pong/CMakeLists.linux-x86_64.txt b/library/cpp/actors/examples/01_ping_pong/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 7320982029..0000000000
--- a/library/cpp/actors/examples/01_ping_pong/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(example_01_ping_pong)
-target_link_libraries(example_01_ping_pong PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-actors-core
-)
-target_link_options(example_01_ping_pong PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(example_01_ping_pong PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/01_ping_pong/main.cpp
-)
-target_allocator(example_01_ping_pong
- library-cpp-lfalloc
-)
-vcs_info(example_01_ping_pong)
diff --git a/library/cpp/actors/examples/01_ping_pong/CMakeLists.txt b/library/cpp/actors/examples/01_ping_pong/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/examples/01_ping_pong/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/examples/01_ping_pong/CMakeLists.windows-x86_64.txt b/library/cpp/actors/examples/01_ping_pong/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 22c41768c9..0000000000
--- a/library/cpp/actors/examples/01_ping_pong/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(example_01_ping_pong)
-target_link_libraries(example_01_ping_pong PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-actors-core
-)
-target_sources(example_01_ping_pong PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/01_ping_pong/main.cpp
-)
-target_allocator(example_01_ping_pong
- library-cpp-lfalloc
-)
-vcs_info(example_01_ping_pong)
diff --git a/library/cpp/actors/examples/01_ping_pong/main.cpp b/library/cpp/actors/examples/01_ping_pong/main.cpp
deleted file mode 100644
index 437f06eadd..0000000000
--- a/library/cpp/actors/examples/01_ping_pong/main.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-#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/log.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/util/should_continue.h>
-#include <util/system/sigset.h>
-#include <util/generic/xrange.h>
-
-using namespace NActors;
-
-static TProgramShouldContinue ShouldContinue;
-
-void OnTerminate(int) {
- ShouldContinue.ShouldStop();
-}
-
-class TPingActor : public TActorBootstrapped<TPingActor> {
- const TActorId Target;
- ui64 HandledEvents;
- TInstant PeriodStart;
-
- void Handle(TEvents::TEvPing::TPtr &ev) {
- Send(ev->Sender, new TEvents::TEvPong());
- Send(ev->Sender, new TEvents::TEvPing());
- Become(&TThis::StatePing);
- }
-
- void Handle(TEvents::TEvPong::TPtr &ev) {
- Y_UNUSED(ev);
- Become(&TThis::StateWait);
- }
-
- void PrintStats() {
- const i64 ms = (TInstant::Now() - PeriodStart).MilliSeconds();
- Cout << "Handled " << 2 * HandledEvents << " over " << ms << "ms" << Endl;
- ScheduleStats();
- }
-
- void ScheduleStats() {
- HandledEvents = 0;
- PeriodStart = TInstant::Now();
- Schedule(TDuration::Seconds(1), new TEvents::TEvWakeup());
- }
-
-public:
- TPingActor(TActorId target)
- : Target(target)
- , HandledEvents(0)
- , PeriodStart(TInstant::Now())
- {}
-
- STFUNC(StateWait) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvents::TEvPing, Handle);
- sFunc(TEvents::TEvWakeup, PrintStats);
- }
-
- ++HandledEvents;
- }
-
- STFUNC(StatePing) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvents::TEvPong, Handle);
- sFunc(TEvents::TEvWakeup, PrintStats);
- }
-
- ++HandledEvents;
- }
-
- void Bootstrap() {
- if (Target) {
- Become(&TThis::StatePing);
- Send(Target, new TEvents::TEvPing());
- ScheduleStats();
- }
- else {
- Become(&TThis::StateWait);
- };
- }
-};
-
-THolder<TActorSystemSetup> BuildActorSystemSetup(ui32 threads, ui32 pools) {
- Y_ABORT_UNLESS(threads > 0 && threads < 100);
- Y_ABORT_UNLESS(pools > 0 && pools < 10);
-
- auto setup = MakeHolder<TActorSystemSetup>();
-
- setup->NodeId = 1;
-
- setup->ExecutorsCount = pools;
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[pools]);
- for (ui32 idx : xrange(pools)) {
- setup->Executors[idx] = new TBasicExecutorPool(idx, threads, 50);
- }
-
- setup->Scheduler = new TBasicSchedulerThread(TSchedulerConfig(512, 0));
-
- return setup;
-}
-
-int main(int argc, char **argv) {
- Y_UNUSED(argc);
- Y_UNUSED(argv);
-
-#ifdef _unix_
- signal(SIGPIPE, SIG_IGN);
-#endif
- signal(SIGINT, &OnTerminate);
- signal(SIGTERM, &OnTerminate);
-
- THolder<TActorSystemSetup> actorSystemSetup = BuildActorSystemSetup(2, 1);
- TActorSystem actorSystem(actorSystemSetup);
-
- actorSystem.Start();
-
- const TActorId a = actorSystem.Register(new TPingActor(TActorId()));
- const TActorId b = actorSystem.Register(new TPingActor(a));
- Y_UNUSED(b);
-
- while (ShouldContinue.PollState() == TProgramShouldContinue::Continue) {
- Sleep(TDuration::MilliSeconds(200));
- }
-
- actorSystem.Stop();
- actorSystem.Cleanup();
-
- return ShouldContinue.GetReturnCode();
-}
diff --git a/library/cpp/actors/examples/01_ping_pong/ya.make b/library/cpp/actors/examples/01_ping_pong/ya.make
deleted file mode 100644
index d33cfd3456..0000000000
--- a/library/cpp/actors/examples/01_ping_pong/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-PROGRAM(example_01_ping_pong)
-
-ALLOCATOR(LF)
-
-SRCS(
- main.cpp
-)
-
-PEERDIR(
- library/cpp/actors/core
-)
-
-END()
diff --git a/library/cpp/actors/examples/02_discovery/CMakeLists.darwin-arm64.txt b/library/cpp/actors/examples/02_discovery/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 5e379dc7ca..0000000000
--- a/library/cpp/actors/examples/02_discovery/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_executable(example_02_discovery)
-target_link_libraries(example_02_discovery PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-actors-dnsresolver
- cpp-actors-interconnect
- cpp-actors-http
- contrib-libs-protobuf
-)
-target_link_options(example_02_discovery PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_proto_messages(example_02_discovery PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/protocol.proto
-)
-target_sources(example_02_discovery PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/endpoint.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/lookup.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/main.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/publish.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/replica.cpp
-)
-target_allocator(example_02_discovery
- library-cpp-lfalloc
-)
-target_proto_addincls(example_02_discovery
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_SOURCE_DIR}/contrib/libs/opentelemetry-proto
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(example_02_discovery
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
-vcs_info(example_02_discovery)
diff --git a/library/cpp/actors/examples/02_discovery/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/examples/02_discovery/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 1003ca94c5..0000000000
--- a/library/cpp/actors/examples/02_discovery/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_executable(example_02_discovery)
-target_link_libraries(example_02_discovery PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-actors-core
- cpp-actors-dnsresolver
- cpp-actors-interconnect
- cpp-actors-http
- contrib-libs-protobuf
-)
-target_link_options(example_02_discovery PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_proto_messages(example_02_discovery PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/protocol.proto
-)
-target_sources(example_02_discovery PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/endpoint.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/lookup.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/main.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/publish.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/replica.cpp
-)
-target_allocator(example_02_discovery
- library-cpp-lfalloc
-)
-target_proto_addincls(example_02_discovery
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_SOURCE_DIR}/contrib/libs/opentelemetry-proto
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(example_02_discovery
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
-vcs_info(example_02_discovery)
diff --git a/library/cpp/actors/examples/02_discovery/CMakeLists.linux-aarch64.txt b/library/cpp/actors/examples/02_discovery/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 564892d9f7..0000000000
--- a/library/cpp/actors/examples/02_discovery/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_executable(example_02_discovery)
-target_link_libraries(example_02_discovery PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-actors-dnsresolver
- cpp-actors-interconnect
- cpp-actors-http
- contrib-libs-protobuf
-)
-target_link_options(example_02_discovery PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_proto_messages(example_02_discovery PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/protocol.proto
-)
-target_sources(example_02_discovery PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/endpoint.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/lookup.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/main.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/publish.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/replica.cpp
-)
-target_allocator(example_02_discovery
- library-cpp-lfalloc
-)
-target_proto_addincls(example_02_discovery
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_SOURCE_DIR}/contrib/libs/opentelemetry-proto
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(example_02_discovery
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
-vcs_info(example_02_discovery)
diff --git a/library/cpp/actors/examples/02_discovery/CMakeLists.linux-x86_64.txt b/library/cpp/actors/examples/02_discovery/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index aed3404cb8..0000000000
--- a/library/cpp/actors/examples/02_discovery/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_executable(example_02_discovery)
-target_link_libraries(example_02_discovery PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-actors-core
- cpp-actors-dnsresolver
- cpp-actors-interconnect
- cpp-actors-http
- contrib-libs-protobuf
-)
-target_link_options(example_02_discovery PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_proto_messages(example_02_discovery PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/protocol.proto
-)
-target_sources(example_02_discovery PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/endpoint.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/lookup.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/main.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/publish.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/replica.cpp
-)
-target_allocator(example_02_discovery
- library-cpp-lfalloc
-)
-target_proto_addincls(example_02_discovery
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_SOURCE_DIR}/contrib/libs/opentelemetry-proto
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(example_02_discovery
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
-vcs_info(example_02_discovery)
diff --git a/library/cpp/actors/examples/02_discovery/CMakeLists.txt b/library/cpp/actors/examples/02_discovery/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/examples/02_discovery/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/examples/02_discovery/CMakeLists.windows-x86_64.txt b/library/cpp/actors/examples/02_discovery/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 6bf59ae8c9..0000000000
--- a/library/cpp/actors/examples/02_discovery/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_executable(example_02_discovery)
-target_link_libraries(example_02_discovery PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-actors-core
- cpp-actors-dnsresolver
- cpp-actors-interconnect
- cpp-actors-http
- contrib-libs-protobuf
-)
-target_proto_messages(example_02_discovery PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/protocol.proto
-)
-target_sources(example_02_discovery PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/endpoint.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/lookup.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/main.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/publish.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/examples/02_discovery/replica.cpp
-)
-target_allocator(example_02_discovery
- library-cpp-lfalloc
-)
-target_proto_addincls(example_02_discovery
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_SOURCE_DIR}/contrib/libs/opentelemetry-proto
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(example_02_discovery
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
-vcs_info(example_02_discovery)
diff --git a/library/cpp/actors/examples/02_discovery/endpoint.cpp b/library/cpp/actors/examples/02_discovery/endpoint.cpp
deleted file mode 100644
index 38c068ca8f..0000000000
--- a/library/cpp/actors/examples/02_discovery/endpoint.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include "services.h"
-
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/protos/services_common.pb.h>
-
-#include <library/cpp/actors/http/http.h>
-#include <library/cpp/actors/http/http_proxy.h>
-
-#include <util/system/hostname.h>
-#include <util/string/builder.h>
-
-class TExampleHttpRequest : public TActor<TExampleHttpRequest> {
- TIntrusivePtr<TExampleStorageConfig> Config;
- const TString PublishKey;
-
- TActorId HttpProxy;
- NHttp::THttpIncomingRequestPtr Request;
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr &ev) {
- Request = std::move(ev->Get()->Request);
- HttpProxy = ev->Sender;
-
- Register(CreateLookupActor(Config.Get(), PublishKey, SelfId()));
- }
-
- void Handle(TEvExample::TEvInfo::TPtr &ev) {
- auto *msg = ev->Get();
-
- TStringBuilder body;
- for (const auto &x : msg->Payloads)
- body << x << Endl;
-
- auto response = Request->CreateResponseOK(body, "application/text; charset=utf-8");
- Send(HttpProxy, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
-
- PassAway();
- }
-public:
- static constexpr IActor::EActivityType ActorActivityType() {
- // define app-specific activity tag to track elapsed cpu | handled events | actor count in Solomon
- return EActorActivity::ACTORLIB_COMMON;
- }
-
- TExampleHttpRequest(TExampleStorageConfig *config, const TString &publishKey)
- : TActor(&TThis::StateWork)
- , Config(config)
- , PublishKey(publishKey)
- {}
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
- hFunc(TEvExample::TEvInfo, Handle);
- }
- }
-};
-
-class TExampleHttpEndpoint : public TActorBootstrapped<TExampleHttpEndpoint> {
- TIntrusivePtr<TExampleStorageConfig> Config;
- const TString PublishKey;
- const ui16 HttpPort;
-
- TActorId PublishActor;
- TActorId HttpProxy;
-
- std::shared_ptr<NMonitoring::TMetricRegistry> SensorsRegistry = std::make_shared<NMonitoring::TMetricRegistry>();
-
- void PassAway() override {
- Send(PublishActor, new TEvents::TEvPoison());
- Send(HttpProxy, new TEvents::TEvPoison());
-
- return TActor::PassAway();
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr &ev) {
- const TActorId reqActor = Register(new TExampleHttpRequest(Config.Get(), PublishKey));
- TlsActivationContext->Send(ev->Forward(reqActor));
- }
-
-public:
- static constexpr IActor::EActivityType ActorActivityType() {
- // define app-specific activity tag to track elapsed cpu | handled events | actor count in Solomon
- return EActorActivity::ACTORLIB_COMMON;
- }
-
- TExampleHttpEndpoint(TExampleStorageConfig *config, const TString &publishKey, ui16 port)
- : Config(config)
- , PublishKey(publishKey)
- , HttpPort(port)
- {
- }
-
- void Bootstrap() {
- const TString publishPayload = ToString(HttpPort);
- PublishActor = Register(CreatePublishActor(Config.Get(), PublishKey, publishPayload));
- HttpProxy = Register(NHttp::CreateHttpProxy(SensorsRegistry));
-
- Send(HttpProxy, new NHttp::TEvHttpProxy::TEvAddListeningPort(HttpPort, FQDNHostName()));
- Send(HttpProxy, new NHttp::TEvHttpProxy::TEvRegisterHandler("/list", SelfId()));
-
- Become(&TThis::StateWork);
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
- default:
- break;
- }
- }
-};
-
-IActor* CreateEndpointActor(TExampleStorageConfig *config, const TString &publishKey, ui16 port) {
- return new TExampleHttpEndpoint(config, publishKey, port);
-}
diff --git a/library/cpp/actors/examples/02_discovery/lookup.cpp b/library/cpp/actors/examples/02_discovery/lookup.cpp
deleted file mode 100644
index fb136a431c..0000000000
--- a/library/cpp/actors/examples/02_discovery/lookup.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-#include "services.h"
-
-#include <library/cpp/actors/core/actorsystem.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <util/generic/set.h>
-#include <util/generic/vector.h>
-
-class TExampleLookupRequestActor : public TActor<TExampleLookupRequestActor> {
- const TActorId Owner;
- const TActorId Replica;
- const TString Key;
-
- void Registered(TActorSystem* sys, const TActorId&) override {
- const auto flags = IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession;
- sys->Send(new IEventHandle(Replica, SelfId(), new TEvExample::TEvReplicaLookup(Key), flags));
- }
-
- void PassAway() override {
- const ui32 replicaNode = Replica.NodeId();
- if (replicaNode != SelfId().NodeId()) {
- const TActorId &interconnectProxy = TlsActivationContext->ExecutorThread.ActorSystem->InterconnectProxy(Replica.NodeId());
- Send(interconnectProxy, new TEvents::TEvUnsubscribe());
- }
- return IActor::PassAway();
- }
-
- void Handle(TEvExample::TEvReplicaInfo::TPtr &ev) {
- Send(Owner, ev->Release().Release());
- return PassAway();
- }
-
- void HandleUndelivered() {
- Send(Owner, new TEvExample::TEvReplicaInfo(Key));
- return PassAway();
- }
-public:
- static constexpr IActor::EActivityType ActorActivityType() {
- // define app-specific activity tag to track elapsed cpu | handled events | actor count in Solomon
- return EActorActivity::ACTORLIB_COMMON;
- }
-
- TExampleLookupRequestActor(TActorId owner, TActorId replica, const TString &key)
- : TActor(&TThis::StateWork)
- , Owner(owner)
- , Replica(replica)
- , Key(key)
- {}
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvExample::TEvReplicaInfo, Handle);
- sFunc(TEvents::TEvUndelivered, HandleUndelivered);
- sFunc(TEvInterconnect::TEvNodeDisconnected, HandleUndelivered);
- default:
- break;
- }
- }
-};
-
-class TExampleLookupActor : public TActorBootstrapped<TExampleLookupActor> {
- TIntrusiveConstPtr<TExampleStorageConfig> Config;
- const TString Key;
- const TActorId ReplyTo;
- TVector<TActorId> RequestActors;
-
- ui32 TotalReplicas = 0;
- ui32 RepliedSuccess = 0;
- ui32 RepliedError = 0;
-
- TSet<TString> Payloads;
-
- void Handle(TEvExample::TEvReplicaInfo::TPtr &ev) {
- NActorsExample::TEvReplicaInfo &record = ev->Get()->Record;
- if (record.PayloadSize()) {
- ++RepliedSuccess;
- for (const TString &payload : record.GetPayload()) {
- Payloads.insert(payload);
- }
- }
- else {
- ++RepliedError;
- }
-
- const ui32 majority = (TotalReplicas / 2 + 1);
- if (RepliedSuccess == majority || (RepliedSuccess + RepliedError == TotalReplicas))
- return ReplyAndDie();
- }
-
- void ReplyAndDie() {
- TVector<TString> replyPayloads(Payloads.begin(), Payloads.end());
- Send(ReplyTo, new TEvExample::TEvInfo(Key, std::move(replyPayloads)));
- return PassAway();
- }
-public:
- static constexpr IActor::EActivityType ActorActivityType() {
- // define app-specific activity tag to track elapsed cpu | handled events | actor count in Solomon
- return EActorActivity::ACTORLIB_COMMON;
- }
-
- TExampleLookupActor(TExampleStorageConfig *config, const TString &key, TActorId replyTo)
- : Config(config)
- , Key(key)
- , ReplyTo(replyTo)
- {}
-
- void Bootstrap() {
- Y_ABORT_UNLESS(Config->Replicas.size() > 0);
-
- TotalReplicas = Config->Replicas.size();
- RequestActors.reserve(TotalReplicas);
- for (const auto &replica : Config->Replicas) {
- const TActorId requestActor = Register(new TExampleLookupRequestActor(SelfId(), replica, Key));
- RequestActors.emplace_back(requestActor);
- }
-
- Become(&TThis::StateWork);
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvExample::TEvReplicaInfo, Handle);
- default:
- break;
- }
- }
-};
-
-IActor* CreateLookupActor(TExampleStorageConfig *config, const TString &key, TActorId replyTo) {
- return new TExampleLookupActor(config, key, replyTo);
-}
diff --git a/library/cpp/actors/examples/02_discovery/main.cpp b/library/cpp/actors/examples/02_discovery/main.cpp
deleted file mode 100644
index 9dec850c77..0000000000
--- a/library/cpp/actors/examples/02_discovery/main.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "services.h"
-
-#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/log.h>
-#include <library/cpp/actors/dnsresolver/dnsresolver.h>
-#include <library/cpp/actors/interconnect/interconnect.h>
-#include <library/cpp/actors/interconnect/interconnect_common.h>
-#include <library/cpp/actors/interconnect/interconnect_tcp_proxy.h>
-#include <library/cpp/actors/interconnect/interconnect_tcp_server.h>
-#include <library/cpp/actors/interconnect/poller_actor.h>
-#include <library/cpp/actors/interconnect/poller_tcp.h>
-#include <library/cpp/actors/util/should_continue.h>
-
-#include <util/system/sigset.h>
-#include <util/generic/xrange.h>
-
-using namespace NActors;
-using namespace NActors::NDnsResolver;
-
-static const ui32 CfgTotalReplicaNodes = 5;
-static const ui16 CfgBasePort = 13300;
-static const ui16 CfgHttpPort = 8881;
-static const TString PublishKey = "endpoint";
-
-static TProgramShouldContinue ShouldContinue;
-
-void OnTerminate(int) {
- ShouldContinue.ShouldStop();
-}
-
-THolder<TActorSystemSetup> BuildActorSystemSetup(ui32 nodeId, ui32 threads, NMonitoring::TDynamicCounters &counters) {
- Y_ABORT_UNLESS(threads > 0 && threads < 100);
-
- auto setup = MakeHolder<TActorSystemSetup>();
-
- setup->NodeId = nodeId;
-
- setup->ExecutorsCount = 1;
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[1]);
- setup->Executors[0] = new TBasicExecutorPool(0, threads, 50);
- setup->Scheduler = new TBasicSchedulerThread(TSchedulerConfig(512, 0));
-
- setup->LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(), TMailboxType::ReadAsFilled, 0));
-
- TIntrusivePtr<TTableNameserverSetup> nameserverTable = new TTableNameserverSetup();
- for (ui32 xnode : xrange<ui32>(1, CfgTotalReplicaNodes + 1)) {
- nameserverTable->StaticNodeTable[xnode] = std::make_pair("127.0.0.1", CfgBasePort + xnode);
- }
-
- setup->LocalServices.emplace_back(
- MakeDnsResolverActorId(),
- TActorSetupCmd(CreateOnDemandDnsResolver(), TMailboxType::ReadAsFilled, 0)
- );
-
- setup->LocalServices.emplace_back(
- GetNameserviceActorId(),
- TActorSetupCmd(CreateNameserverTable(nameserverTable), TMailboxType::ReadAsFilled, 0)
- );
-
- TIntrusivePtr<TInterconnectProxyCommon> icCommon = new TInterconnectProxyCommon();
- icCommon->NameserviceId = GetNameserviceActorId();
- icCommon->MonCounters = counters.GetSubgroup("counters", "interconnect");
- icCommon->TechnicalSelfHostName = "127.0.0.1";
-
- setup->Interconnect.ProxyActors.resize(CfgTotalReplicaNodes + 1);
- for (ui32 xnode : xrange<ui32>(1, CfgTotalReplicaNodes + 1)) {
- if (xnode != nodeId) {
- IActor *actor = new TInterconnectProxyTCP(xnode, icCommon);
- setup->Interconnect.ProxyActors[xnode] = TActorSetupCmd(actor, TMailboxType::ReadAsFilled, 0);
- }
- else {
- IActor *listener = new TInterconnectListenerTCP("127.0.0.1", CfgBasePort + xnode, icCommon);
- setup->LocalServices.emplace_back(
- MakeInterconnectListenerActorId(false),
- TActorSetupCmd(listener, TMailboxType::ReadAsFilled, 0)
- );
- }
- }
-
- return setup;
-}
-
-int main(int argc, char **argv) {
- Y_UNUSED(argc);
- Y_UNUSED(argv);
-
-#ifdef _unix_
- signal(SIGPIPE, SIG_IGN);
-#endif
- signal(SIGINT, &OnTerminate);
- signal(SIGTERM, &OnTerminate);
-
- TIntrusivePtr<TExampleStorageConfig> config = new TExampleStorageConfig();
- for (ui32 nodeid : xrange<ui32>(1, CfgTotalReplicaNodes + 1)) {
- config->Replicas.push_back(MakeReplicaId(nodeid));
- }
-
- TVector<THolder<TActorSystem>> actorSystemHolder;
- TVector<TIntrusivePtr<NMonitoring::TDynamicCounters>> countersHolder;
- for (ui32 nodeid : xrange<ui32>(1, CfgTotalReplicaNodes + 1)) {
- countersHolder.emplace_back(new NMonitoring::TDynamicCounters());
- THolder<TActorSystemSetup> actorSystemSetup = BuildActorSystemSetup(nodeid, 2, *countersHolder.back());
- actorSystemSetup->LocalServices.emplace_back(
- TActorId(),
- TActorSetupCmd(CreateEndpointActor(config.Get(), PublishKey, CfgHttpPort + nodeid), TMailboxType::HTSwap, 0)
- );
-
- actorSystemSetup->LocalServices.emplace_back(
- MakeReplicaId(nodeid),
- TActorSetupCmd(CreateReplica(), TMailboxType::ReadAsFilled, 0)
- );
-
- actorSystemHolder.emplace_back(new TActorSystem(actorSystemSetup));
- }
-
- for (auto &xh : actorSystemHolder)
- xh->Start();
-
- while (ShouldContinue.PollState() == TProgramShouldContinue::Continue) {
- Sleep(TDuration::MilliSeconds(200));
- }
-
- // stop actorsystem to not generate new reqeusts for external services
- // no events would be processed anymore
- for (auto &xh : actorSystemHolder)
- xh->Stop();
-
- // and then cleanup actorsystem
- // from this moment working with actorsystem prohibited
- for (auto &xh : actorSystemHolder)
- xh->Cleanup();
-
- return ShouldContinue.GetReturnCode();
-}
diff --git a/library/cpp/actors/examples/02_discovery/protocol.proto b/library/cpp/actors/examples/02_discovery/protocol.proto
deleted file mode 100644
index 41cc2cc9c8..0000000000
--- a/library/cpp/actors/examples/02_discovery/protocol.proto
+++ /dev/null
@@ -1,19 +0,0 @@
-package NActorsExample;
-
-message TEvReplicaInfo {
- optional string Key = 1;
- repeated string Payload = 2;
-};
-
-message TEvReplicaPublishAck {
- optional string Key = 1;
-};
-
-message TEvReplicaPublish {
- optional string Key = 1;
- optional string Payload = 2;
-};
-
-message TEvReplicaLookup {
- optional string Key = 1;
-};
diff --git a/library/cpp/actors/examples/02_discovery/publish.cpp b/library/cpp/actors/examples/02_discovery/publish.cpp
deleted file mode 100644
index d923283e6b..0000000000
--- a/library/cpp/actors/examples/02_discovery/publish.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-#include "services.h"
-
-#include <library/cpp/actors/core/actorsystem.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <util/generic/set.h>
-#include <util/generic/vector.h>
-
-class TExamplePublishReplicaActor : public TActorBootstrapped<TExamplePublishReplicaActor> {
- const TActorId Owner;
- const TActorId Replica;
- const TString Key;
- const TString Payload;
-
- void PassAway() override {
- const ui32 replicaNode = Replica.NodeId();
- if (replicaNode != SelfId().NodeId()) {
- const TActorId &interconnectProxy = TlsActivationContext->ExecutorThread.ActorSystem->InterconnectProxy(Replica.NodeId());
- Send(interconnectProxy, new TEvents::TEvUnsubscribe());
- }
- return IActor::PassAway();
- }
-
- void SomeSleep() {
- Become(&TThis::StateSleep, TDuration::MilliSeconds(250), new TEvents::TEvWakeup());
- }
-public:
- static constexpr IActor::EActivityType ActorActivityType() {
- // define app-specific activity tag to track elapsed cpu | handled events | actor count in Solomon
- return EActorActivity::ACTORLIB_COMMON;
- }
-
- TExamplePublishReplicaActor(TActorId owner, TActorId replica, const TString &key, const TString &payload)
- : Owner(owner)
- , Replica(replica)
- , Key(key)
- , Payload(payload)
- {}
-
- void Bootstrap() {
- const ui32 flags = IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession;
- Send(Replica, new TEvExample::TEvReplicaPublish(Key, Payload), flags);
- Become(&TThis::StatePublish);
- }
-
- STFUNC(StatePublish) {
- switch (ev->GetTypeRewrite()) {
- sFunc(TEvents::TEvPoison, PassAway);
- sFunc(TEvents::TEvUndelivered, SomeSleep);
- sFunc(TEvInterconnect::TEvNodeDisconnected, SomeSleep);
- default:
- break;
- }
- }
-
- STFUNC(StateSleep) {
- switch (ev->GetTypeRewrite()) {
- sFunc(TEvents::TEvPoison, PassAway);
- sFunc(TEvents::TEvWakeup, Bootstrap);
- default:
- break;
- }
- }
-};
-
-class TExamplePublishActor : public TActorBootstrapped<TExamplePublishActor> {
- TIntrusiveConstPtr<TExampleStorageConfig> Config;
- const TString Key;
- const TString Payload;
- TVector<TActorId> PublishActors;
-
- void PassAway() override {
- for (const auto &x : PublishActors)
- Send(x, new TEvents::TEvPoison());
- return IActor::PassAway();
- }
-public:
- static constexpr IActor::EActivityType ActorActivityType() {
- // define app-specific activity tag to track elapsed cpu | handled events | actor count in Solomon
- return EActorActivity::ACTORLIB_COMMON;
- }
-
- TExamplePublishActor(TExampleStorageConfig *config, const TString &key, const TString &what)
- : Config(config)
- , Key(key)
- , Payload(what)
- {}
-
- void Bootstrap() {
- for (auto &replica : Config->Replicas) {
- const TActorId x = Register(new TExamplePublishReplicaActor(SelfId(), replica, Key, Payload));
- PublishActors.emplace_back(x);
- }
-
- Become(&TThis::StateWork);
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- sFunc(TEvents::TEvPoison, PassAway);
- default:
- break;
- }
- }
-};
-
-IActor* CreatePublishActor(TExampleStorageConfig *config, const TString &key, const TString &what) {
- return new TExamplePublishActor(config, key, what);
-}
diff --git a/library/cpp/actors/examples/02_discovery/replica.cpp b/library/cpp/actors/examples/02_discovery/replica.cpp
deleted file mode 100644
index 96a6f5f475..0000000000
--- a/library/cpp/actors/examples/02_discovery/replica.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-#include "services.h"
-#include <library/cpp/actors/core/actorsystem.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/interconnect.h>
-#include <util/generic/set.h>
-#include <util/generic/hash_set.h>
-#include <util/generic/vector.h>
-
-class TExampleReplicaActor : public TActor<TExampleReplicaActor> {
- using TOwnerIndex = TMap<TActorId, ui32, TActorId::TOrderedCmp>;
- using TKeyIndex = THashMap<TString, TSet<ui32>>;
-
- struct TEntry {
- TString Payload;
- TActorId Owner;
- TOwnerIndex::iterator OwnerIt;
- TKeyIndex::iterator KeyIt;
- };
-
- TVector<TEntry> Entries;
- TVector<ui32> AvailableEntries;
-
- TOwnerIndex IndexOwner;
- TKeyIndex IndexKey;
-
- ui32 AllocateEntry() {
- ui32 ret;
- if (AvailableEntries) {
- ret = AvailableEntries.back();
- AvailableEntries.pop_back();
- }
- else {
- ret = Entries.size();
- Entries.emplace_back();
- }
-
- return ret;
- }
-
- bool IsLastEntryOnNode(TOwnerIndex::iterator ownerIt) {
- const ui32 ownerNodeId = ownerIt->first.NodeId();
- if (ownerIt != IndexOwner.begin()) {
- auto x = ownerIt;
- --x;
- if (x->first.NodeId() == ownerNodeId)
- return false;
- }
-
- ++ownerIt;
- if (ownerIt != IndexOwner.end()) {
- if (ownerIt->first.NodeId() == ownerNodeId)
- return false;
- }
-
- return true;
- }
-
- void CleanupEntry(ui32 entryIndex) {
- TEntry &entry = Entries[entryIndex];
- entry.KeyIt->second.erase(entryIndex);
- if (entry.KeyIt->second.empty())
- IndexKey.erase(entry.KeyIt);
-
- if (IsLastEntryOnNode(entry.OwnerIt))
- Send(TlsActivationContext->ExecutorThread.ActorSystem->InterconnectProxy(entry.OwnerIt->first.NodeId()), new TEvents::TEvUnsubscribe());
-
- IndexOwner.erase(entry.OwnerIt);
-
- TString().swap(entry.Payload);
- entry.Owner = TActorId();
- entry.KeyIt = IndexKey.end();
- entry.OwnerIt = IndexOwner.end();
-
- AvailableEntries.emplace_back(entryIndex);
- }
-
- void Handle(TEvExample::TEvReplicaLookup::TPtr &ev) {
- auto &record = ev->Get()->Record;
- const auto &key = record.GetKey();
-
- auto keyIt = IndexKey.find(key);
- if (keyIt == IndexKey.end()) {
- Send(ev->Sender, new TEvExample::TEvReplicaInfo(key), 0, ev->Cookie);
- return;
- }
-
- auto reply = MakeHolder<TEvExample::TEvReplicaInfo>(key);
- reply->Record.MutablePayload()->Reserve(keyIt->second.size());
- for (ui32 entryIndex : keyIt->second) {
- const TEntry &entry = Entries[entryIndex];
- reply->Record.AddPayload(entry.Payload);
- }
-
- Send(ev->Sender, std::move(reply), 0, ev->Cookie);
- }
-
- void Handle(TEvExample::TEvReplicaPublish::TPtr &ev) {
- auto &record = ev->Get()->Record;
- const TString &key = record.GetKey();
- const TString &payload = record.GetPayload();
- const TActorId &owner = ev->Sender;
-
- auto ownerIt = IndexOwner.find(owner);
- if (ownerIt != IndexOwner.end()) {
- const ui32 entryIndex = ownerIt->second;
- TEntry &entry = Entries[entryIndex];
- if (entry.KeyIt->first != key) {
- // reply nothing, request suspicious
- return;
- }
-
- entry.Payload = payload;
- }
- else {
- const ui32 entryIndex = AllocateEntry();
- TEntry &entry = Entries[entryIndex];
-
- entry.Payload = payload;
- entry.Owner = owner;
-
- entry.OwnerIt = IndexOwner.emplace(owner, entryIndex).first;
- entry.KeyIt = IndexKey.emplace(std::make_pair(key, TSet<ui32>())).first;
- entry.KeyIt->second.emplace(entryIndex);
-
- Send(owner, new TEvExample::TEvReplicaPublishAck(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, ev->Cookie);
- }
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr &ev) {
- auto ownerIt = IndexOwner.find(ev->Sender);
- if (ownerIt == IndexOwner.end())
- return;
-
- CleanupEntry(ownerIt->second);
- }
-
- void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr &ev) {
- auto *msg = ev->Get();
- const ui32 nodeId = msg->NodeId;
- auto ownerIt = IndexOwner.lower_bound(TActorId(nodeId, 0, 0, 0));
- while (ownerIt != IndexOwner.end() && ownerIt->first.NodeId() == nodeId) {
- const ui32 idx = ownerIt->second;
- ++ownerIt;
- CleanupEntry(idx);
- }
- }
-
-public:
- static constexpr IActor::EActivityType ActorActivityType() {
- // define app-specific activity tag to track elapsed cpu | handled events | actor count in Solomon
- return EActorActivity::ACTORLIB_COMMON;
- }
-
- TExampleReplicaActor()
- : TActor(&TThis::StateWork)
- {}
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvExample::TEvReplicaLookup, Handle);
- hFunc(TEvExample::TEvReplicaPublish, Handle);
- hFunc(TEvents::TEvUndelivered, Handle);
- hFunc(TEvInterconnect::TEvNodeDisconnected, Handle);
-
- IgnoreFunc(TEvInterconnect::TEvNodeConnected);
- default:
- // here is place to spam some log message on unknown events
- break;
- }
- }
-};
-
-IActor* CreateReplica() {
- return new TExampleReplicaActor();
-}
-
-TActorId MakeReplicaId(ui32 nodeid) {
- char x[12] = { 'r', 'p', 'l' };
- memcpy(x + 5, &nodeid, sizeof(ui32));
- return TActorId(nodeid, TStringBuf(x, 12));
-}
diff --git a/library/cpp/actors/examples/02_discovery/services.h b/library/cpp/actors/examples/02_discovery/services.h
deleted file mode 100644
index 266517c577..0000000000
--- a/library/cpp/actors/examples/02_discovery/services.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#pragma once
-#include <library/cpp/actors/examples/02_discovery/protocol.pb.h>
-
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/actors/core/event_pb.h>
-#include <library/cpp/actors/core/event_local.h>
-
-#include <util/generic/vector.h>
-
-using namespace NActors;
-
-struct TExampleStorageConfig : public TThrRefBase {
- TVector<TActorId> Replicas;
-};
-
-struct TEvExample {
- enum EEv {
- EvReplicaLookup = EventSpaceBegin(TEvents::ES_USERSPACE + 1),
- EvReplicaPublish,
-
- EvReplicaInfo = EventSpaceBegin(TEvents::ES_USERSPACE + 2),
- EvReplicaPublishAck,
-
- EvInfo = EventSpaceBegin(TEvents::ES_USERSPACE + 3),
- };
-
- struct TEvReplicaLookup : public TEventPB<TEvReplicaLookup, NActorsExample::TEvReplicaLookup, EvReplicaLookup> {
- TEvReplicaLookup()
- {}
-
- TEvReplicaLookup(const TString &key)
- {
- Record.SetKey(key);
- }
- };
-
- struct TEvReplicaPublish : public TEventPB<TEvReplicaPublish, NActorsExample::TEvReplicaPublish, EvReplicaPublish> {
- TEvReplicaPublish()
- {}
-
- TEvReplicaPublish(const TString &key, const TString &payload)
- {
- Record.SetKey(key);
- Record.SetPayload(payload);
- }
- };
-
- struct TEvReplicaInfo : public TEventPB<TEvReplicaInfo, NActorsExample::TEvReplicaInfo, EvReplicaInfo> {
- TEvReplicaInfo()
- {}
-
- TEvReplicaInfo(const TString &key)
- {
- Record.SetKey(key);
- }
- };
-
- struct TEvReplicaPublishAck : public TEventPB<TEvReplicaPublishAck, NActorsExample::TEvReplicaPublishAck, EvReplicaPublishAck> {
- TEvReplicaPublishAck()
- {}
-
- TEvReplicaPublishAck(const TString &key)
- {
- Record.SetKey(key);
- }
- };
-
- struct TEvInfo : public TEventLocal<TEvInfo, EvInfo> {
- const TString Key;
- const TVector<TString> Payloads;
-
- TEvInfo(const TString &key, TVector<TString> &&payloads)
- : Key(key)
- , Payloads(payloads)
- {}
- };
-};
-
-IActor* CreateReplica();
-IActor* CreatePublishActor(TExampleStorageConfig *config, const TString &key, const TString &what);
-IActor* CreateLookupActor(TExampleStorageConfig *config, const TString &key, TActorId replyTo);
-IActor* CreateEndpointActor(TExampleStorageConfig *config, const TString &publishKey, ui16 httpPort);
-
-TActorId MakeReplicaId(ui32 nodeid);
diff --git a/library/cpp/actors/examples/02_discovery/ya.make b/library/cpp/actors/examples/02_discovery/ya.make
deleted file mode 100644
index 953c13259c..0000000000
--- a/library/cpp/actors/examples/02_discovery/ya.make
+++ /dev/null
@@ -1,25 +0,0 @@
-PROGRAM(example_02_discovery)
-
-ALLOCATOR(LF)
-
-SRCS(
- endpoint.cpp
- lookup.cpp
- main.cpp
- publish.cpp
- replica.cpp
- services.h
-)
-
-SRCS(
- protocol.proto
-)
-
-PEERDIR(
- library/cpp/actors/core
- library/cpp/actors/dnsresolver
- library/cpp/actors/interconnect
- library/cpp/actors/http
-)
-
-END()
diff --git a/library/cpp/actors/examples/CMakeLists.txt b/library/cpp/actors/examples/CMakeLists.txt
deleted file mode 100644
index bcda1cfeef..0000000000
--- a/library/cpp/actors/examples/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(01_ping_pong)
-add_subdirectory(02_discovery)
diff --git a/library/cpp/actors/examples/ya.make b/library/cpp/actors/examples/ya.make
deleted file mode 100644
index 0a98074b47..0000000000
--- a/library/cpp/actors/examples/ya.make
+++ /dev/null
@@ -1,4 +0,0 @@
-RECURSE(
- 01_ping_pong
- 02_discovery
-)
diff --git a/library/cpp/actors/helpers/CMakeLists.darwin-arm64.txt b/library/cpp/actors/helpers/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 7367c0b925..0000000000
--- a/library/cpp/actors/helpers/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-helpers)
-target_link_libraries(cpp-actors-helpers PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-monlib-dynamic_counters
-)
-target_sources(cpp-actors-helpers PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/activeactors.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/flow_controlled_queue.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/selfping_actor.cpp
-)
diff --git a/library/cpp/actors/helpers/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/helpers/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 7367c0b925..0000000000
--- a/library/cpp/actors/helpers/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-helpers)
-target_link_libraries(cpp-actors-helpers PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-monlib-dynamic_counters
-)
-target_sources(cpp-actors-helpers PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/activeactors.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/flow_controlled_queue.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/selfping_actor.cpp
-)
diff --git a/library/cpp/actors/helpers/CMakeLists.linux-aarch64.txt b/library/cpp/actors/helpers/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index da8ce6e8e6..0000000000
--- a/library/cpp/actors/helpers/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-helpers)
-target_link_libraries(cpp-actors-helpers PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-monlib-dynamic_counters
-)
-target_sources(cpp-actors-helpers PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/activeactors.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/flow_controlled_queue.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/selfping_actor.cpp
-)
diff --git a/library/cpp/actors/helpers/CMakeLists.linux-x86_64.txt b/library/cpp/actors/helpers/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index da8ce6e8e6..0000000000
--- a/library/cpp/actors/helpers/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-helpers)
-target_link_libraries(cpp-actors-helpers PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-monlib-dynamic_counters
-)
-target_sources(cpp-actors-helpers PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/activeactors.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/flow_controlled_queue.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/selfping_actor.cpp
-)
diff --git a/library/cpp/actors/helpers/CMakeLists.txt b/library/cpp/actors/helpers/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/helpers/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/helpers/CMakeLists.windows-x86_64.txt b/library/cpp/actors/helpers/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 7367c0b925..0000000000
--- a/library/cpp/actors/helpers/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-helpers)
-target_link_libraries(cpp-actors-helpers PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-monlib-dynamic_counters
-)
-target_sources(cpp-actors-helpers PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/activeactors.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/flow_controlled_queue.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/selfping_actor.cpp
-)
diff --git a/library/cpp/actors/helpers/activeactors.cpp b/library/cpp/actors/helpers/activeactors.cpp
deleted file mode 100644
index 145e97dc57..0000000000
--- a/library/cpp/actors/helpers/activeactors.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "activeactors.h"
-
diff --git a/library/cpp/actors/helpers/activeactors.h b/library/cpp/actors/helpers/activeactors.h
deleted file mode 100644
index ec482e93c8..0000000000
--- a/library/cpp/actors/helpers/activeactors.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#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.
- ////////////////////////////////////////////////////////////////////////////
- class TActiveActors : public THashSet<TActorId> {
- public:
- void Insert(const TActorId &aid) {
- bool inserted = insert(aid).second;
- Y_ABORT_UNLESS(inserted);
- }
-
- void Insert(const TActiveActors &moreActors) {
- for (const auto &aid : moreActors) {
- Insert(aid);
- }
- }
-
- void Erase(const TActorId &aid) {
- auto num = erase(aid);
- Y_ABORT_UNLESS(num == 1);
- }
-
- size_t KillAndClear(const TActorContext &ctx) {
- size_t s = size(); // number of actors managed
- for (const auto &x: *this) {
- ctx.Send(x, new TEvents::TEvPoisonPill());
- }
- clear();
- return s; // how many actors we killed
- }
- };
-
-} // NKikimr
-
diff --git a/library/cpp/actors/helpers/flow_controlled_queue.cpp b/library/cpp/actors/helpers/flow_controlled_queue.cpp
deleted file mode 100644
index 49ed7c79f0..0000000000
--- a/library/cpp/actors/helpers/flow_controlled_queue.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-#include "flow_controlled_queue.h"
-
-#include <library/cpp/actors/core/interconnect.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/util/datetime.h>
-
-#include <util/generic/deque.h>
-#include <util/datetime/cputimer.h>
-#include <util/generic/algorithm.h>
-
-namespace NActors {
-
-class TFlowControlledRequestQueue;
-
-class TFlowControlledRequestActor : public IActorCallback {
- TFlowControlledRequestQueue * const QueueActor;
-
- void HandleReply(TAutoPtr<IEventHandle> &ev);
- void HandleUndelivered(TEvents::TEvUndelivered::TPtr &ev);
-public:
- const TActorId Source;
- const ui64 Cookie;
- const ui32 Flags;
- const ui64 StartCounter;
-
- TFlowControlledRequestActor(ui32 activity, TFlowControlledRequestQueue *queue, TActorId source, ui64 cookie, ui32 flags)
- : IActorCallback(static_cast<TReceiveFunc>(&TFlowControlledRequestActor::StateWait), activity)
- , QueueActor(queue)
- , Source(source)
- , Cookie(cookie)
- , Flags(flags)
- , StartCounter(GetCycleCountFast())
- {}
-
- STATEFN(StateWait) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvents::TEvUndelivered, HandleUndelivered);
- default:
- HandleReply(ev);
- }
- }
-
- TDuration AccumulatedLatency() const {
- const ui64 cc = GetCycleCountFast() - StartCounter;
- return CyclesToDuration(cc);
- }
-
- using IActor::PassAway;
-};
-
-class TFlowControlledRequestQueue : public IActorCallback {
- const TActorId Target;
- const TFlowControlledQueueConfig Config;
-
- TDeque<THolder<IEventHandle>> UnhandledRequests;
- TDeque<TFlowControlledRequestActor *> RegisteredRequests;
-
- bool Subscribed = false;
-
- TDuration MinimalSeenLatency;
-
- bool CanRegister() {
- const ui64 inFly = RegisteredRequests.size();
- if (inFly <= Config.MinAllowedInFly) // <= for handling minAllowed == 0
- return true;
-
- if (inFly >= Config.MaxAllowedInFly)
- return false;
-
- if (Config.TargetDynamicRate) {
- if (const ui64 dynMax = MinimalSeenLatency.MicroSeconds() * Config.TargetDynamicRate / 1000000) {
- if (inFly >= dynMax)
- return false;
- }
- }
-
- const TDuration currentLatency = RegisteredRequests.front()->AccumulatedLatency();
- if (currentLatency <= Config.MinTrackedLatency)
- return true;
-
- if (currentLatency <= MinimalSeenLatency * Config.LatencyFactor)
- return true;
-
- return false;
- }
-
- void HandleForwardedEvent(TAutoPtr<IEventHandle> &ev) {
- if (CanRegister()) {
- RegisterReqActor(ev);
- } else {
- UnhandledRequests.emplace_back(ev.Release());
- }
- }
-
- void RegisterReqActor(THolder<IEventHandle> ev) {
- TFlowControlledRequestActor *reqActor = new TFlowControlledRequestActor(ActivityType, this, ev->Sender, ev->Cookie, ev->Flags);
- const TActorId reqActorId = RegisterWithSameMailbox(reqActor);
- RegisteredRequests.emplace_back(reqActor);
-
- if (!Subscribed && (Target.NodeId() != SelfId().NodeId())) {
- Send(TActivationContext::InterconnectProxy(Target.NodeId()), new TEvents::TEvSubscribe(), IEventHandle::FlagTrackDelivery);
- Subscribed = true;
- }
-
- TActivationContext::Send(new IEventHandle(Target, reqActorId, ev.Get()->ReleaseBase().Release(), IEventHandle::FlagTrackDelivery, ev->Cookie));
- }
-
- void PumpQueue() {
- while (RegisteredRequests && RegisteredRequests.front() == nullptr)
- RegisteredRequests.pop_front();
-
- while (UnhandledRequests && CanRegister()) {
- RegisterReqActor(std::move(UnhandledRequests.front()));
- UnhandledRequests.pop_front();
- }
- }
-
- void HandleDisconnected() {
- Subscribed = false;
-
- const ui32 nodeid = Target.NodeId();
- for (TFlowControlledRequestActor *reqActor : RegisteredRequests) {
- if (reqActor) {
- if (reqActor->Flags & IEventHandle::FlagSubscribeOnSession) {
- TActivationContext::Send(
- new IEventHandle(reqActor->Source, TActorId(), new TEvInterconnect::TEvNodeDisconnected(nodeid), 0, reqActor->Cookie)
- );
- }
- reqActor->PassAway();
- }
- }
-
- RegisteredRequests.clear();
-
- for (auto &ev : UnhandledRequests) {
- const auto reason = TEvents::TEvUndelivered::Disconnected;
- if (ev->Flags & IEventHandle::FlagTrackDelivery) {
- TActivationContext::Send(
- new IEventHandle(ev->Sender, ev->Recipient, new TEvents::TEvUndelivered(ev->GetTypeRewrite(), reason), 0, ev->Cookie)
- );
- }
- }
-
- UnhandledRequests.clear();
- }
-
- void HandlePoison() {
- HandleDisconnected();
-
- if (SelfId().NodeId() != Target.NodeId())
- Send(TActivationContext::InterconnectProxy(Target.NodeId()), new TEvents::TEvUnsubscribe());
-
- PassAway();
- }
-public:
- template <class TEnum>
- TFlowControlledRequestQueue(TActorId target, const TEnum activity, const TFlowControlledQueueConfig &config)
- : IActorCallback(static_cast<TReceiveFunc>(&TFlowControlledRequestQueue::StateWork), activity)
- , Target(target)
- , Config(config)
- , MinimalSeenLatency(TDuration::Seconds(1))
- {}
-
- STATEFN(StateWork) {
- switch (ev->GetTypeRewrite()) {
- cFunc(TEvInterconnect::TEvNodeDisconnected::EventType, HandleDisconnected);
- IgnoreFunc(TEvInterconnect::TEvNodeConnected);
- cFunc(TEvents::TEvUndelivered::EventType, HandleDisconnected);
- cFunc(TEvents::TEvPoison::EventType, HandlePoison);
- default:
- HandleForwardedEvent(ev);
- }
- }
-
- void HandleRequestReply(TAutoPtr<IEventHandle> &ev, TFlowControlledRequestActor *reqActor) {
- auto it = Find(RegisteredRequests, reqActor);
- if (it == RegisteredRequests.end())
- return;
- TActivationContext::Send(ev->Forward(reqActor->Source).Release());
- const TDuration reqLatency = reqActor->AccumulatedLatency();
- if (reqLatency < MinimalSeenLatency)
- MinimalSeenLatency = reqLatency;
-
- *it = nullptr;
- PumpQueue();
- }
-
- void HandleRequestUndelivered(TEvents::TEvUndelivered::TPtr &ev, TFlowControlledRequestActor *reqActor) {
- auto it = Find(RegisteredRequests, reqActor);
- if (it == RegisteredRequests.end())
- return;
-
- TActivationContext::Send(ev->Forward(reqActor->Source).Release());
-
- *it = nullptr;
- PumpQueue();
- }
-};
-
-void TFlowControlledRequestActor::HandleReply(TAutoPtr<IEventHandle> &ev) {
- QueueActor->HandleRequestReply(ev, this);
- PassAway();
-}
-
-void TFlowControlledRequestActor::HandleUndelivered(TEvents::TEvUndelivered::TPtr &ev) {
- QueueActor->HandleRequestUndelivered(ev, this);
- PassAway();
-}
-
-template <class TEnum>
-IActor* CreateFlowControlledRequestQueue(TActorId targetId, const TEnum activity, const TFlowControlledQueueConfig &config) {
- return new TFlowControlledRequestQueue(targetId, activity, config);
-}
-
-}
diff --git a/library/cpp/actors/helpers/flow_controlled_queue.h b/library/cpp/actors/helpers/flow_controlled_queue.h
deleted file mode 100644
index bbfffa18d7..0000000000
--- a/library/cpp/actors/helpers/flow_controlled_queue.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-
-namespace NActors {
-
- struct TFlowControlledQueueConfig {
- ui32 MinAllowedInFly = 20;
- ui32 MaxAllowedInFly = 100;
- ui32 TargetDynamicRate = 0;
-
- TDuration MinTrackedLatency = TDuration::MilliSeconds(20);
- ui32 LatencyFactor = 4;
- };
-
- template <class TEnum = IActor::EActivityType>
- IActor* CreateFlowControlledRequestQueue(TActorId targetId, const TEnum activity = IActor::EActivityType::ACTORLIB_COMMON, const TFlowControlledQueueConfig &config = TFlowControlledQueueConfig());
-
-}
diff --git a/library/cpp/actors/helpers/future_callback.h b/library/cpp/actors/helpers/future_callback.h
deleted file mode 100644
index 6626dd439d..0000000000
--- a/library/cpp/actors/helpers/future_callback.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/hfunc.h>
-
-namespace NActors {
-
-template <typename EventType>
-struct TActorFutureCallback : TActor<TActorFutureCallback<EventType>> {
- using TCallback = std::function<void(TAutoPtr<TEventHandle<EventType>>&)>;
- using TBase = TActor<TActorFutureCallback<EventType>>;
- TCallback Callback;
-
- static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::EActivityType::ACTOR_FUTURE_CALLBACK;
- }
-
- TActorFutureCallback(TCallback&& callback)
- : TBase(&TActorFutureCallback::StateWaitForEvent)
- , Callback(std::move(callback))
- {}
-
- STRICT_STFUNC(StateWaitForEvent,
- HFunc(EventType, Handle)
- )
-
- void Handle(typename EventType::TPtr ev, const TActorContext& ctx) {
- Callback(ev);
- TBase::Die(ctx);
- }
-};
-
-} // NActors
diff --git a/library/cpp/actors/helpers/mon_histogram_helper.h b/library/cpp/actors/helpers/mon_histogram_helper.h
deleted file mode 100644
index 2c5ef0bbee..0000000000
--- a/library/cpp/actors/helpers/mon_histogram_helper.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#pragma once
-
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-#include <util/string/cast.h>
-
-namespace NActors {
- namespace NMon {
- class THistogramCounterHelper {
- public:
- THistogramCounterHelper()
- : FirstBucketVal(0)
- , BucketCount(0)
- {
- }
-
- THistogramCounterHelper(const THistogramCounterHelper&) = default;
-
- void Init(NMonitoring::TDynamicCounters* group, const TString& baseName, const TString& unit,
- ui64 firstBucket, ui64 bucketCnt, bool useSensorLabelName = true)
- {
- Y_ASSERT(FirstBucketVal == 0);
- Y_ASSERT(BucketCount == 0);
-
- FirstBucketVal = firstBucket;
- BucketCount = bucketCnt;
- BucketsHolder.reserve(BucketCount);
- Buckets.reserve(BucketCount);
- for (size_t i = 0; i < BucketCount; ++i) {
- TString bucketName = GetBucketName(i) + " " + unit;
- auto labelName = useSensorLabelName ? "sensor" : "name";
- BucketsHolder.push_back(group->GetSubgroup(labelName, baseName)->GetNamedCounter("range", bucketName, true));
- Buckets.push_back(BucketsHolder.back().Get());
- }
- }
-
- void Add(ui64 val) {
- Y_ASSERT(FirstBucketVal != 0);
- Y_ASSERT(BucketCount != 0);
- Y_ABORT_UNLESS(val <= (1ULL << 63ULL));
- size_t ind = 0;
- if (val > FirstBucketVal) {
- ind = GetValueBitCount((2 * val - 1) / FirstBucketVal) - 1;
- if (ind >= BucketCount) {
- ind = BucketCount - 1;
- }
- }
- Buckets[ind]->Inc();
- }
-
- ui64 GetBucketCount() const {
- return BucketCount;
- }
-
- ui64 GetBucketValue(size_t index) const {
- Y_ASSERT(index < BucketCount);
- return Buckets[index]->Val();
- }
-
- void SetBucketValue(ui64 index, ui64 value) {
- Y_ASSERT(index < BucketCount);
- *Buckets[index] = value;
- }
-
- private:
- TString GetBucketName(size_t ind) const {
- Y_ASSERT(FirstBucketVal != 0);
- Y_ASSERT(BucketCount != 0);
- Y_ASSERT(ind < BucketCount);
- if (ind + 1 < BucketCount) {
- return ToString<ui64>(FirstBucketVal << ind);
- } else {
- // Last slot is up to +INF
- return "INF";
- }
- }
-
- private:
- ui64 FirstBucketVal;
- ui64 BucketCount;
- TVector<NMonitoring::TDynamicCounters::TCounterPtr> BucketsHolder;
- TVector<NMonitoring::TDeprecatedCounter*> Buckets;
- };
-
- }
-}
diff --git a/library/cpp/actors/helpers/selfping_actor.cpp b/library/cpp/actors/helpers/selfping_actor.cpp
deleted file mode 100644
index f9f7c297fc..0000000000
--- a/library/cpp/actors/helpers/selfping_actor.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-#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 {
-
-ui64 MeasureTaskDurationNs() {
- // Prepare worm test data
- // 11 * 11 * 3 * 8 = 2904 bytes, fits in L1 cache
- constexpr ui64 Size = 11;
- // Align the data to reduce random alignment effects
- alignas(64) TStackVec<ui64, Size * Size * 3> data;
- ui64 s = 0;
- NHPTimer::STime beginTime;
- NHPTimer::STime endTime;
- // Prepare the data
- data.resize(Size * Size * 3);
- for (ui64 matrixIdx = 0; matrixIdx < 3; ++matrixIdx) {
- for (ui64 y = 0; y < Size; ++y) {
- for (ui64 x = 0; x < Size; ++x) {
- data[matrixIdx * (Size * Size) + y * Size + x] = y * Size + x;
- }
- }
- }
- // Warm-up the cache
- NHPTimer::GetTime(&beginTime);
- for (ui64 idx = 0; idx < data.size(); ++idx) {
- s += data[idx];
- }
- NHPTimer::GetTime(&endTime);
- s += (ui64)(1000000.0 * NHPTimer::GetSeconds(endTime - beginTime));
-
- // Measure the CPU performance
- // C = A * B with injected dependency to s
- NHPTimer::GetTime(&beginTime);
- for (ui64 y = 0; y < Size; ++y) {
- for (ui64 x = 0; x < Size; ++x) {
- for (ui64 i = 0; i < Size; ++i) {
- s += data[y * Size + i] * data[Size * Size + i * Size + x];
- }
- data[2 * Size * Size + y * Size + x] = s;
- s = 0;
- }
- }
- for (ui64 idx = 0; idx < data.size(); ++idx) {
- s += data[idx];
- }
- NHPTimer::GetTime(&endTime);
- // Prepare the result
- double d = 1000000000.0 * (NHPTimer::GetSeconds(endTime - beginTime) + 0.000000001 * (s & 1));
- return (ui64)d;
-}
-
-namespace {
-
-struct TEvPing: public TEventLocal<TEvPing, TEvents::THelloWorld::Ping> {
- TEvPing(double timeStart)
- : TimeStart(timeStart)
- {}
-
- const double TimeStart;
-};
-
-template <class TValueType_>
-struct TAvgOperation {
- struct TValueType {
- ui64 Count = 0;
- TValueType_ Sum = TValueType_();
- };
- using TValueVector = TVector<TValueType>;
-
- static constexpr TValueType InitialValue() {
- return TValueType(); // zero
- }
-
- // Updates value in current bucket and returns window value
- static TValueType UpdateBucket(TValueType windowValue, TValueVector& buckets, size_t index, TValueType newVal) {
- Y_ASSERT(index < buckets.size());
- buckets[index].Sum += newVal.Sum;
- buckets[index].Count += newVal.Count;
- windowValue.Sum += newVal.Sum;
- windowValue.Count += newVal.Count;
- return windowValue;
- }
-
- static TValueType ClearBuckets(TValueType windowValue, TValueVector& buckets, size_t firstElemIndex, size_t bucketsToClear) {
- Y_ASSERT(!buckets.empty());
- Y_ASSERT(firstElemIndex < buckets.size());
- Y_ASSERT(bucketsToClear <= buckets.size());
-
- const size_t arraySize = buckets.size();
- for (size_t i = 0; i < bucketsToClear; ++i) {
- TValueType& curVal = buckets[firstElemIndex];
- windowValue.Sum -= curVal.Sum;
- windowValue.Count -= curVal.Count;
- curVal = InitialValue();
- firstElemIndex = (firstElemIndex + 1) % arraySize;
- }
- return windowValue;
- }
-
-};
-
-class TSelfPingActor : public TActorBootstrapped<TSelfPingActor> {
-private:
- const TDuration SendInterval;
- const NMonitoring::TDynamicCounters::TCounterPtr MaxPingCounter;
- const NMonitoring::TDynamicCounters::TCounterPtr AvgPingCounter;
- const NMonitoring::TDynamicCounters::TCounterPtr AvgPingCounterWithSmallWindow;
- const NMonitoring::TDynamicCounters::TCounterPtr CalculationTimeCounter;
-
- NSlidingWindow::TSlidingWindow<NSlidingWindow::TMaxOperation<ui64>> MaxPingSlidingWindow;
- NSlidingWindow::TSlidingWindow<TAvgOperation<ui64>> AvgPingSlidingWindow;
- NSlidingWindow::TSlidingWindow<TAvgOperation<ui64>> AvgPingSmallSlidingWindow;
- NSlidingWindow::TSlidingWindow<TAvgOperation<ui64>> CalculationSlidingWindow;
-
- THPTimer Timer;
-
-public:
- static constexpr auto ActorActivityType() {
- return EActivityType::SELF_PING_ACTOR;
- }
-
- TSelfPingActor(TDuration sendInterval,
- const NMonitoring::TDynamicCounters::TCounterPtr& maxPingCounter,
- const NMonitoring::TDynamicCounters::TCounterPtr& avgPingCounter,
- const NMonitoring::TDynamicCounters::TCounterPtr& avgPingSmallWindowCounter,
- const NMonitoring::TDynamicCounters::TCounterPtr& calculationTimeCounter)
- : SendInterval(sendInterval)
- , MaxPingCounter(maxPingCounter)
- , AvgPingCounter(avgPingCounter)
- , AvgPingCounterWithSmallWindow(avgPingSmallWindowCounter)
- , CalculationTimeCounter(calculationTimeCounter)
- , MaxPingSlidingWindow(TDuration::Seconds(15), 100)
- , AvgPingSlidingWindow(TDuration::Seconds(15), 100)
- , AvgPingSmallSlidingWindow(TDuration::Seconds(1), 100)
- , CalculationSlidingWindow(TDuration::Seconds(15), 100)
- {
- }
-
- void Bootstrap(const TActorContext& ctx)
- {
- Become(&TSelfPingActor::RunningState);
- SchedulePing(ctx, Timer.Passed());
- }
-
- STFUNC(RunningState)
- {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvPing, HandlePing);
- default:
- Y_ABORT("TSelfPingActor::RunningState: unexpected event 0x%08" PRIx32, ev->GetTypeRewrite());
- }
- }
-
- void HandlePing(TEvPing::TPtr &ev, const TActorContext &ctx)
- {
- const auto now = ctx.Now();
- const double hpNow = Timer.Passed();
- const auto& e = *ev->Get();
- const double passedTime = hpNow - e.TimeStart;
- const ui64 delayUs = passedTime > 0.0 ? static_cast<ui64>(passedTime * 1e6) : 0;
-
- if (MaxPingCounter) {
- *MaxPingCounter = MaxPingSlidingWindow.Update(delayUs, now);
- }
- if (AvgPingCounter) {
- auto res = AvgPingSlidingWindow.Update({1, delayUs}, now);
- *AvgPingCounter = double(res.Sum) / double(res.Count + 1);
- }
- if (AvgPingCounterWithSmallWindow) {
- auto res = AvgPingSmallSlidingWindow.Update({1, delayUs}, now);
- *AvgPingCounterWithSmallWindow = double(res.Sum) / double(res.Count + 1);
- }
-
- if (CalculationTimeCounter) {
- ui64 d = MeasureTaskDurationNs();
- auto res = CalculationSlidingWindow.Update({1, d}, now);
- *CalculationTimeCounter = double(res.Sum) / double(res.Count + 1);
- }
-
- SchedulePing(ctx, hpNow);
- }
-
-private:
- void SchedulePing(const TActorContext &ctx, double hpNow) const
- {
- ctx.Schedule(SendInterval, new TEvPing(hpNow));
- }
-};
-
-} // namespace
-
-IActor* CreateSelfPingActor(
- TDuration sendInterval,
- const NMonitoring::TDynamicCounters::TCounterPtr& maxPingCounter,
- const NMonitoring::TDynamicCounters::TCounterPtr& avgPingCounter,
- const NMonitoring::TDynamicCounters::TCounterPtr& avgPingSmallWindowCounter,
- const NMonitoring::TDynamicCounters::TCounterPtr& calculationTimeCounter)
-{
- return new TSelfPingActor(sendInterval, maxPingCounter, avgPingCounter, avgPingSmallWindowCounter, calculationTimeCounter);
-}
-
-} // NActors
diff --git a/library/cpp/actors/helpers/selfping_actor.h b/library/cpp/actors/helpers/selfping_actor.h
deleted file mode 100644
index a06bfe8292..0000000000
--- a/library/cpp/actors/helpers/selfping_actor.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-namespace NActors {
-
-ui64 MeasureTaskDurationNs();
-NActors::IActor* CreateSelfPingActor(
- TDuration sendInterval,
- const NMonitoring::TDynamicCounters::TCounterPtr& maxPingCounter,
- const NMonitoring::TDynamicCounters::TCounterPtr& avgPingCounter,
- const NMonitoring::TDynamicCounters::TCounterPtr& avgPingSmallWindowCounter,
- const NMonitoring::TDynamicCounters::TCounterPtr& calculationTimeCounter);
-
-} // NActors
diff --git a/library/cpp/actors/helpers/selfping_actor_ut.cpp b/library/cpp/actors/helpers/selfping_actor_ut.cpp
deleted file mode 100644
index 542f817755..0000000000
--- a/library/cpp/actors/helpers/selfping_actor_ut.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#include "selfping_actor.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/actors/testlib/test_runtime.h>
-
-namespace NActors {
-namespace Tests {
-
-THolder<TTestActorRuntimeBase> CreateRuntime() {
- auto runtime = MakeHolder<TTestActorRuntimeBase>();
- runtime->SetScheduledEventFilter([](auto&&, auto&&, auto&&, auto&&) { return false; });
- runtime->Initialize();
- return runtime;
-}
-
-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 counter2(new NMonitoring::TCounterForPtr());
- NMonitoring::TDynamicCounters::TCounterPtr counter3(new NMonitoring::TCounterForPtr());
- NMonitoring::TDynamicCounters::TCounterPtr counter4(new NMonitoring::TCounterForPtr());
-
- auto actor = CreateSelfPingActor(
- TDuration::MilliSeconds(100), // sendInterval (unused in test)
- counter, counter2, counter3, counter4);
-
- UNIT_ASSERT_VALUES_EQUAL(counter->Val(), 0);
- UNIT_ASSERT_VALUES_EQUAL(counter2->Val(), 0);
- UNIT_ASSERT_VALUES_EQUAL(counter3->Val(), 0);
- UNIT_ASSERT_VALUES_EQUAL(counter4->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
diff --git a/library/cpp/actors/helpers/ut/CMakeLists.darwin-arm64.txt b/library/cpp/actors/helpers/ut/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 0112181222..0000000000
--- a/library/cpp/actors/helpers/ut/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-helpers-ut)
-target_include_directories(library-cpp-actors-helpers-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers
-)
-target_link_libraries(library-cpp-actors-helpers-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-helpers
- cpp-actors-interconnect
- cpp-actors-testlib
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-helpers-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-helpers-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/selfping_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-helpers-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-helpers-ut
- TEST_TARGET
- library-cpp-actors-helpers-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-helpers-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-helpers-ut)
diff --git a/library/cpp/actors/helpers/ut/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/helpers/ut/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 126b29e574..0000000000
--- a/library/cpp/actors/helpers/ut/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-helpers-ut)
-target_include_directories(library-cpp-actors-helpers-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers
-)
-target_link_libraries(library-cpp-actors-helpers-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-helpers
- cpp-actors-interconnect
- cpp-actors-testlib
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-helpers-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-helpers-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/selfping_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-helpers-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-helpers-ut
- TEST_TARGET
- library-cpp-actors-helpers-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-helpers-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-helpers-ut)
diff --git a/library/cpp/actors/helpers/ut/CMakeLists.linux-aarch64.txt b/library/cpp/actors/helpers/ut/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 24da0dacd6..0000000000
--- a/library/cpp/actors/helpers/ut/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-helpers-ut)
-target_include_directories(library-cpp-actors-helpers-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers
-)
-target_link_libraries(library-cpp-actors-helpers-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-helpers
- cpp-actors-interconnect
- cpp-actors-testlib
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-helpers-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-helpers-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/selfping_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-helpers-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-helpers-ut
- TEST_TARGET
- library-cpp-actors-helpers-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-helpers-ut
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-helpers-ut)
diff --git a/library/cpp/actors/helpers/ut/CMakeLists.linux-x86_64.txt b/library/cpp/actors/helpers/ut/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index db118dc91e..0000000000
--- a/library/cpp/actors/helpers/ut/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-helpers-ut)
-target_include_directories(library-cpp-actors-helpers-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers
-)
-target_link_libraries(library-cpp-actors-helpers-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-helpers
- cpp-actors-interconnect
- cpp-actors-testlib
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-helpers-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-helpers-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/selfping_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-helpers-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-helpers-ut
- TEST_TARGET
- library-cpp-actors-helpers-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-helpers-ut
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-helpers-ut)
diff --git a/library/cpp/actors/helpers/ut/CMakeLists.txt b/library/cpp/actors/helpers/ut/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/helpers/ut/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/helpers/ut/CMakeLists.windows-x86_64.txt b/library/cpp/actors/helpers/ut/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 7e68870a0e..0000000000
--- a/library/cpp/actors/helpers/ut/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-helpers-ut)
-target_include_directories(library-cpp-actors-helpers-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers
-)
-target_link_libraries(library-cpp-actors-helpers-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-helpers
- cpp-actors-interconnect
- cpp-actors-testlib
- cpp-actors-core
-)
-target_sources(library-cpp-actors-helpers-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/helpers/selfping_actor_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-helpers-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-helpers-ut
- TEST_TARGET
- library-cpp-actors-helpers-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-helpers-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-helpers-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-helpers-ut)
diff --git a/library/cpp/actors/helpers/ut/ya.make b/library/cpp/actors/helpers/ut/ya.make
deleted file mode 100644
index 10b298bb72..0000000000
--- a/library/cpp/actors/helpers/ut/ya.make
+++ /dev/null
@@ -1,31 +0,0 @@
-UNITTEST_FOR(library/cpp/actors/helpers)
-
-FORK_SUBTESTS()
-IF (SANITIZER_TYPE)
- SIZE(LARGE)
- TIMEOUT(1200)
- TAG(ya:fat)
- SPLIT_FACTOR(20)
- REQUIREMENTS(
- ram:32
- )
-ELSE()
- SIZE(MEDIUM)
- TIMEOUT(600)
- REQUIREMENTS(
- ram:16
- )
-ENDIF()
-
-
-PEERDIR(
- library/cpp/actors/interconnect
- library/cpp/actors/testlib
- library/cpp/actors/core
-)
-
-SRCS(
- selfping_actor_ut.cpp
-)
-
-END()
diff --git a/library/cpp/actors/helpers/ya.make b/library/cpp/actors/helpers/ya.make
deleted file mode 100644
index 94acdca726..0000000000
--- a/library/cpp/actors/helpers/ya.make
+++ /dev/null
@@ -1,23 +0,0 @@
-LIBRARY()
-
-SRCS(
- activeactors.cpp
- activeactors.h
- flow_controlled_queue.cpp
- flow_controlled_queue.h
- future_callback.h
- mon_histogram_helper.h
- selfping_actor.cpp
-)
-
-PEERDIR(
- library/cpp/actors/core
- library/cpp/monlib/dynamic_counters
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- ut
-)
-
diff --git a/library/cpp/actors/http/CMakeLists.darwin-arm64.txt b/library/cpp/actors/http/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 1947b6fa39..0000000000
--- a/library/cpp/actors/http/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-http)
-target_link_libraries(cpp-actors-http PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-openssl
- contrib-libs-zlib
- cpp-actors-core
- cpp-actors-interconnect
- library-cpp-dns
- cpp-monlib-metrics
- cpp-string_utils-quote
-)
-target_sources(cpp-actors-http PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_cache.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_compress.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_acceptor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_incoming.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_outgoing.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_static.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http.cpp
-)
diff --git a/library/cpp/actors/http/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/http/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 1947b6fa39..0000000000
--- a/library/cpp/actors/http/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-http)
-target_link_libraries(cpp-actors-http PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-openssl
- contrib-libs-zlib
- cpp-actors-core
- cpp-actors-interconnect
- library-cpp-dns
- cpp-monlib-metrics
- cpp-string_utils-quote
-)
-target_sources(cpp-actors-http PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_cache.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_compress.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_acceptor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_incoming.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_outgoing.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_static.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http.cpp
-)
diff --git a/library/cpp/actors/http/CMakeLists.linux-aarch64.txt b/library/cpp/actors/http/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index a0e186fa07..0000000000
--- a/library/cpp/actors/http/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-http)
-target_link_libraries(cpp-actors-http PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-openssl
- contrib-libs-zlib
- cpp-actors-core
- cpp-actors-interconnect
- library-cpp-dns
- cpp-monlib-metrics
- cpp-string_utils-quote
-)
-target_sources(cpp-actors-http PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_cache.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_compress.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_acceptor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_incoming.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_outgoing.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_static.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http.cpp
-)
diff --git a/library/cpp/actors/http/CMakeLists.linux-x86_64.txt b/library/cpp/actors/http/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index a0e186fa07..0000000000
--- a/library/cpp/actors/http/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-http)
-target_link_libraries(cpp-actors-http PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-openssl
- contrib-libs-zlib
- cpp-actors-core
- cpp-actors-interconnect
- library-cpp-dns
- cpp-monlib-metrics
- cpp-string_utils-quote
-)
-target_sources(cpp-actors-http PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_cache.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_compress.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_acceptor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_incoming.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_outgoing.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_static.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http.cpp
-)
diff --git a/library/cpp/actors/http/CMakeLists.txt b/library/cpp/actors/http/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/http/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/http/CMakeLists.windows-x86_64.txt b/library/cpp/actors/http/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 1947b6fa39..0000000000
--- a/library/cpp/actors/http/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-http)
-target_link_libraries(cpp-actors-http PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-openssl
- contrib-libs-zlib
- cpp-actors-core
- cpp-actors-interconnect
- library-cpp-dns
- cpp-monlib-metrics
- cpp-string_utils-quote
-)
-target_sources(cpp-actors-http PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_cache.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_compress.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_acceptor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_incoming.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy_outgoing.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_proxy.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_static.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http.cpp
-)
diff --git a/library/cpp/actors/http/http.cpp b/library/cpp/actors/http/http.cpp
deleted file mode 100644
index 9da46e412b..0000000000
--- a/library/cpp/actors/http/http.cpp
+++ /dev/null
@@ -1,823 +0,0 @@
-#include "http.h"
-#include <library/cpp/string_utils/quote/quote.h>
-
-inline TStringBuf operator +(TStringBuf l, TStringBuf r) {
- if (l.empty()) {
- return r;
- }
- if (r.empty()) {
- return l;
- }
- if (l.end() == r.begin()) {
- return TStringBuf(l.data(), l.size() + r.size());
- }
- if (r.end() == l.begin()) {
- return TStringBuf(r.data(), l.size() + r.size());
- }
- Y_ABORT("oops");
- return TStringBuf();
-}
-
-inline TStringBuf operator +=(TStringBuf& l, TStringBuf r) {
- return l = l + r;
-}
-
-static bool is_not_number(TStringBuf v) {
- return v.empty() || std::find_if_not(v.begin(), v.end(), [](unsigned char c) { return std::isdigit(c); }) != v.end();
-}
-
-namespace NHttp {
-
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::Host>() { return "Host"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::Accept>() { return "Accept"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::Connection>() { return "Connection"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::ContentType>() { return "Content-Type"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::ContentLength>() { return "Content-Length"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::TransferEncoding>() { return "Transfer-Encoding"; }
-template <> TStringBuf THttpRequest::GetName<&THttpRequest::AcceptEncoding>() { return "Accept-Encoding"; }
-
-const TMap<TStringBuf, TStringBuf THttpRequest::*, TLessNoCase> THttpRequest::HeadersLocation = {
- { THttpRequest::GetName<&THttpRequest::Host>(), &THttpRequest::Host },
- { THttpRequest::GetName<&THttpRequest::Accept>(), &THttpRequest::Accept },
- { THttpRequest::GetName<&THttpRequest::Connection>(), &THttpRequest::Connection },
- { THttpRequest::GetName<&THttpRequest::ContentType>(), &THttpRequest::ContentType },
- { THttpRequest::GetName<&THttpRequest::ContentLength>(), &THttpRequest::ContentLength },
- { THttpRequest::GetName<&THttpRequest::TransferEncoding>(), &THttpRequest::TransferEncoding },
- { THttpRequest::GetName<&THttpRequest::AcceptEncoding>(), &THttpRequest::AcceptEncoding },
-};
-
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::Connection>() { return "Connection"; }
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::ContentType>() { return "Content-Type"; }
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::ContentLength>() { return "Content-Length"; }
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::TransferEncoding>() { return "Transfer-Encoding"; }
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::LastModified>() { return "Last-Modified"; }
-template <> TStringBuf THttpResponse::GetName<&THttpResponse::ContentEncoding>() { return "Content-Encoding"; }
-
-const TMap<TStringBuf, TStringBuf THttpResponse::*, TLessNoCase> THttpResponse::HeadersLocation = {
- { THttpResponse::GetName<&THttpResponse::Connection>(), &THttpResponse::Connection },
- { THttpResponse::GetName<&THttpResponse::ContentType>(), &THttpResponse::ContentType },
- { THttpResponse::GetName<&THttpResponse::ContentLength>(), &THttpResponse::ContentLength },
- { THttpResponse::GetName<&THttpResponse::TransferEncoding>(), &THttpResponse::TransferEncoding },
- { THttpResponse::GetName<&THttpResponse::LastModified>(), &THttpResponse::LastModified },
- { THttpResponse::GetName<&THttpResponse::ContentEncoding>(), &THttpResponse::ContentEncoding }
-};
-
-void THttpRequest::Clear() {
- // a dirty little trick
- this->~THttpRequest(); // basically, do nothing
- new (this) THttpRequest(); // reset all fields
-}
-
-template <>
-bool THttpParser<THttpRequest, TSocketBuffer>::HaveBody() const {
- if (!Body.empty()) {
- return true;
- }
- return !ContentLength.empty() || !TransferEncoding.empty();
-}
-
-template <>
-void THttpParser<THttpRequest, TSocketBuffer>::Advance(size_t len) {
- TStringBuf data(Pos(), len);
- while (!data.empty()) {
- if (Stage != EParseStage::Error) {
- LastSuccessStage = Stage;
- }
- switch (Stage) {
- case EParseStage::Method: {
- if (ProcessData(Method, data, ' ', MaxMethodSize)) {
- Stage = EParseStage::URL;
- }
- break;
- }
- case EParseStage::URL: {
- if (ProcessData(URL, data, ' ', MaxURLSize)) {
- Stage = EParseStage::Protocol;
- }
- break;
- }
- case EParseStage::Protocol: {
- if (ProcessData(Protocol, data, '/', MaxProtocolSize)) {
- Stage = EParseStage::Version;
- }
- break;
- }
- case EParseStage::Version: {
- if (ProcessData(Version, data, "\r\n", MaxVersionSize)) {
- Stage = EParseStage::Header;
- Headers = data;
- }
- break;
- }
- case EParseStage::Header: {
- if (ProcessData(Header, data, "\r\n", MaxHeaderSize)) {
- if (Header.empty()) {
- if (HaveBody() && (ContentLength.empty() || ContentLength != "0")) {
- Stage = EParseStage::Body;
- } else if (TotalSize.has_value() && !data.empty()) {
- Stage = EParseStage::Body;
- } else {
- Stage = EParseStage::Done;
- }
- } else {
- ProcessHeader(Header);
- }
- Headers = TStringBuf(Headers.data(), data.data() - Headers.data());
- }
- if (Stage != EParseStage::Body) {
- break;
- }
- [[fallthrough]];
- }
- case EParseStage::Body: {
- if (TEqNoCase()(TransferEncoding, "chunked")) {
- Stage = EParseStage::ChunkLength;
- } else if (!ContentLength.empty()) {
- if (is_not_number(ContentLength)) {
- // Invalid content length
- Stage = EParseStage::Error;
- } else if (ProcessData(Content, data, FromStringWithDefault(ContentLength, 0))) {
- Body = Content;
- Stage = EParseStage::Done;
- }
- } else if (TotalSize.has_value()) {
- if (ProcessData(Content, data, GetBodySizeFromTotalSize())) {
- Body = Content;
- Stage = EParseStage::Done;
- }
- } else {
- // Invalid body encoding
- Stage = EParseStage::Error;
- }
- break;
- }
- case EParseStage::ChunkLength: {
- if (ProcessData(Line, data, "\r\n", MaxChunkLengthSize)) {
- if (!Line.empty()) {
- ChunkLength = ParseHex(Line);
- if (ChunkLength <= MaxChunkSize) {
- ContentSize = Content.size() + ChunkLength;
- if (ContentSize <= MaxChunkContentSize) {
- Stage = EParseStage::ChunkData;
- Line.Clear();
- } else {
- // Invalid chunk content length
- Stage = EParseStage::Error;
- }
- } else {
- // Invalid chunk length
- Stage = EParseStage::Error;
- }
- } else {
- // Invalid body encoding
- Stage = EParseStage::Error;
- }
- }
- break;
- }
- case EParseStage::ChunkData: {
- if (!IsError()) {
- if (ProcessData(Content, data, ContentSize)) {
- if (ProcessData(Line, data, 2)) {
- if (Line == "\r\n") {
- if (ChunkLength == 0) {
- Body = Content;
- Stage = EParseStage::Done;
- } else {
- Stage = EParseStage::ChunkLength;
- }
- Line.Clear();
- } else {
- // Invalid body encoding
- Stage = EParseStage::Error;
- }
- }
- }
- }
- break;
- }
-
- case EParseStage::Done:
- case EParseStage::Error: {
- data.Clear();
- break;
- }
- default:
- Y_ABORT("Invalid processing sequence");
- break;
- }
- }
- TSocketBuffer::Advance(len);
-}
-
-template <>
-THttpParser<THttpRequest, TSocketBuffer>::EParseStage THttpParser<THttpRequest, TSocketBuffer>::GetInitialStage() {
- return EParseStage::Method;
-}
-
-template <>
-bool THttpParser<THttpResponse, TSocketBuffer>::HaveBody() const {
- if (!Body.empty()) {
- return true;
- }
- return (!Status.starts_with("1") && Status != "204" && Status != "304")
- && (!ContentType.empty() || !ContentLength.empty() || !TransferEncoding.empty());
-}
-
-template <>
-THttpParser<THttpResponse, TSocketBuffer>::EParseStage THttpParser<THttpResponse, TSocketBuffer>::GetInitialStage() {
- return EParseStage::Protocol;
-}
-
-void THttpResponse::Clear() {
- // a dirty little trick
- this->~THttpResponse(); // basically, do nothing
- new (this) THttpResponse(); // reset all fields
-}
-
-template <>
-void THttpParser<THttpResponse, TSocketBuffer>::Advance(size_t len) {
- TStringBuf data(Pos(), len);
- while (!data.empty()) {
- if (Stage != EParseStage::Error) {
- LastSuccessStage = Stage;
- }
- switch (Stage) {
- case EParseStage::Protocol: {
- if (ProcessData(Protocol, data, '/', MaxProtocolSize)) {
- Stage = EParseStage::Version;
- }
- break;
- }
- case EParseStage::Version: {
- if (ProcessData(Version, data, ' ', MaxVersionSize)) {
- Stage = EParseStage::Status;
- }
- break;
- }
- case EParseStage::Status: {
- if (ProcessData(Status, data, ' ', MaxStatusSize)) {
- Stage = EParseStage::Message;
- }
- break;
- }
- case EParseStage::Message: {
- if (ProcessData(Message, data, "\r\n", MaxMessageSize)) {
- Stage = EParseStage::Header;
- Headers = TStringBuf(data.data(), size_t(0));
- }
- break;
- }
- case EParseStage::Header: {
- if (ProcessData(Header, data, "\r\n", MaxHeaderSize)) {
- if (Header.empty()) {
- if (HaveBody() && (ContentLength.empty() || ContentLength != "0")) {
- Stage = EParseStage::Body;
- } else if (TotalSize.has_value() && !data.empty()) {
- Stage = EParseStage::Body;
- } else {
- Stage = EParseStage::Done;
- }
- } else {
- ProcessHeader(Header);
- }
- Headers = TStringBuf(Headers.data(), data.data() - Headers.data());
- }
- if (Stage != EParseStage::Body) {
- break;
- }
- [[fallthrough]];
- }
- case EParseStage::Body: {
- if (TEqNoCase()(TransferEncoding, "chunked")) {
- Stage = EParseStage::ChunkLength;
- } else if (!ContentLength.empty()) {
- if (is_not_number(ContentLength)) {
- // Invalid content length
- Stage = EParseStage::Error;
- } else if (ProcessData(Body, data, FromStringWithDefault(ContentLength, 0))) {
- Stage = EParseStage::Done;
- if (Body && ContentEncoding == "deflate") {
- Content = DecompressDeflate(Body);
- Body = Content;
- }
- }
- } else if (TotalSize.has_value()) {
- if (ProcessData(Content, data, GetBodySizeFromTotalSize())) {
- Body = Content;
- Stage = EParseStage::Done;
- if (Body && ContentEncoding == "deflate") {
- Content = DecompressDeflate(Body);
- Body = Content;
- }
- }
- } else {
- // Invalid body encoding
- Stage = EParseStage::Error;
- }
- break;
- }
- case EParseStage::ChunkLength: {
- if (ProcessData(Line, data, "\r\n", MaxChunkLengthSize)) {
- if (!Line.empty()) {
- ChunkLength = ParseHex(Line);
- if (ChunkLength <= MaxChunkSize) {
- ContentSize = Content.size() + ChunkLength;
- if (ContentSize <= MaxChunkContentSize) {
- Stage = EParseStage::ChunkData;
- Line.Clear();
- } else {
- // Invalid chunk content length
- Stage = EParseStage::Error;
- }
- } else {
- // Invalid chunk length
- Stage = EParseStage::Error;
- }
- } else {
- // Invalid body encoding
- Stage = EParseStage::Error;
- }
- }
- break;
- }
- case EParseStage::ChunkData: {
- if (!IsError()) {
- if (ProcessData(Content, data, ContentSize)) {
- if (ProcessData(Line, data, 2)) {
- if (Line == "\r\n") {
- if (ChunkLength == 0) {
- Body = Content;
- Stage = EParseStage::Done;
- if (Body && ContentEncoding == "deflate") {
- Content = DecompressDeflate(Body);
- Body = Content;
- }
- } else {
- Stage = EParseStage::ChunkLength;
- }
- Line.Clear();
- } else {
- // Invalid body encoding
- Stage = EParseStage::Error;
- }
- }
- }
- }
- break;
- }
- case EParseStage::Done:
- case EParseStage::Error:
- data.Clear();
- break;
- default:
- // Invalid processing sequence
- Stage = EParseStage::Error;
- break;
- }
- }
- TSocketBuffer::Advance(len);
-}
-
-template <>
-void THttpParser<THttpResponse, TSocketBuffer>::ConnectionClosed() {
- if (Stage == EParseStage::Done) {
- return;
- }
- if (Stage == EParseStage::Body) {
- // ?
- Stage = EParseStage::Done;
- } else {
- LastSuccessStage = Stage;
- Stage = EParseStage::Error;
- }
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseString(TStringBuf data) {
- THttpParser<THttpResponse, TSocketBuffer> parser(data);
- THeadersBuilder headers(parser.Headers);
- if (!Endpoint->WorkerName.empty()) {
- headers.Set("X-Worker-Name", Endpoint->WorkerName);
- }
- THttpOutgoingResponsePtr response = new THttpOutgoingResponse(this);
- response->InitResponse(parser.Protocol, parser.Version, parser.Status, parser.Message);
- if (parser.HaveBody()) {
- if (parser.ContentType && !Endpoint->CompressContentTypes.empty()) {
- TStringBuf contentType = parser.ContentType.Before(';');
- Trim(contentType, ' ');
- if (Count(Endpoint->CompressContentTypes, contentType) != 0) {
- if (response->EnableCompression()) {
- headers.Erase("Content-Length"); // we will need new length after compression
- }
- }
- }
- headers.Erase("Transfer-Encoding"); // we erase transfer-encoding because we convert body to content-length
- response->Set(headers);
- response->SetBody(parser.Body);
- } else {
- headers.Erase("Transfer-Encoding"); // we erase transfer-encoding because we convert body to content-length
- response->Set(headers);
- if (!response->ContentLength) {
- response->Set<&THttpResponse::ContentLength>("0");
- }
- }
- return response;
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseOK(TStringBuf body, TStringBuf contentType, TInstant lastModified) {
- return CreateResponse("200", "OK", contentType, body, lastModified);
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseBadRequest(TStringBuf html, TStringBuf contentType) {
- if (html.empty() && IsError()) {
- contentType = "text/plain";
- html = GetErrorText();
- }
- return CreateResponse("400", "Bad Request", contentType, html);
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseNotFound(TStringBuf html, TStringBuf contentType) {
- return CreateResponse("404", "Not Found", contentType, html);
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseServiceUnavailable(TStringBuf html, TStringBuf contentType) {
- return CreateResponse("503", "Service Unavailable", contentType, html);
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponseGatewayTimeout(TStringBuf html, TStringBuf contentType) {
- return CreateResponse("504", "Gateway Timeout", contentType, html);
-}
-
-THttpIncomingResponse::THttpIncomingResponse(THttpOutgoingRequestPtr request)
- : Request(request)
-{}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::ConstructResponse(TStringBuf status, TStringBuf message) {
- TStringBuf version = Version;
- if (version != "1.0" && version != "1.1") {
- version = "1.1";
- }
- THttpOutgoingResponsePtr response = new THttpOutgoingResponse(this, "HTTP", version, status, message);
- return response;
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateIncompleteResponse(TStringBuf status, TStringBuf message, const THeaders& headers) {
- THttpOutgoingResponsePtr response = ConstructResponse(status, message);
- if (!headers.Has("Connection")) {
- response->Set<&THttpResponse::Connection>(GetConnection());
- }
- if (!headers.Has("X-Worker-Name")) {
- if (!Endpoint->WorkerName.empty()) {
- response->Set("X-Worker-Name", Endpoint->WorkerName);
- }
- }
- response->Set(headers);
- return response;
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateIncompleteResponse(TStringBuf status, TStringBuf message, const THeaders& headers, TStringBuf body) {
- THttpOutgoingResponsePtr response = CreateIncompleteResponse(status, message, headers);
- if (!response->ContentType.empty() && !body.empty()) {
- if (!Endpoint->CompressContentTypes.empty()) {
- TStringBuf contentType = response->ContentType.Before(';');
- Trim(contentType, ' ');
- if (Count(Endpoint->CompressContentTypes, contentType) != 0) {
- response->EnableCompression();
- }
- }
- }
- return response;
-}
-
-void THttpIncomingRequest::FinishResponse(THttpOutgoingResponsePtr& response, TStringBuf body) {
- if (response->IsNeedBody() || !body.empty()) {
- if (Method == "HEAD") {
- response->Set<&THttpResponse::ContentLength>(ToString(body.size()));
- } else {
- response->SetBody(body);
- }
- }
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponse(TStringBuf status, TStringBuf message) {
- THttpOutgoingResponsePtr response = CreateIncompleteResponse(status, message);
- FinishResponse(response);
- return response;
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponse(TStringBuf status, TStringBuf message, const THeaders& headers) {
- THttpOutgoingResponsePtr response = CreateIncompleteResponse(status, message, headers);
- FinishResponse(response);
- return response;
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponse(TStringBuf status, TStringBuf message, const THeaders& headers, TStringBuf body) {
- THttpOutgoingResponsePtr response = CreateIncompleteResponse(status, message, headers, body);
- FinishResponse(response, body);
- return response;
-}
-
-THttpOutgoingResponsePtr THttpIncomingRequest::CreateResponse(TStringBuf status, TStringBuf message, TStringBuf contentType, TStringBuf body, TInstant lastModified) {
- NHttp::THeadersBuilder headers;
- if (!contentType.empty() && !body.empty()) {
- headers.Set("Content-Type", contentType);
- }
- if (lastModified) {
- headers.Set("Last-Modified", lastModified.FormatGmTime("%a, %d %b %Y %H:%M:%S GMT"));
- }
- return CreateResponse(status, message, headers, body);
-}
-
-THttpIncomingRequestPtr THttpIncomingRequest::Duplicate() {
- THttpIncomingRequestPtr request = new THttpIncomingRequest(*this);
- request->Reparse();
- request->Timer.Reset();
- return request;
-}
-
-THttpIncomingResponsePtr THttpIncomingResponse::Duplicate(THttpOutgoingRequestPtr request) {
- THttpIncomingResponsePtr response = new THttpIncomingResponse(*this);
- response->Reparse();
- response->Request = request;
- return response;
-}
-
-THttpOutgoingResponsePtr THttpOutgoingResponse::Duplicate(THttpIncomingRequestPtr request) {
- THeadersBuilder headers(Headers);
- if (!request->Endpoint->WorkerName.empty()) {
- headers.Set("X-Worker-Name", request->Endpoint->WorkerName);
- }
- THttpOutgoingResponsePtr response = new THttpOutgoingResponse(request);
- response->InitResponse(Protocol, Version, Status, Message);
- if (Body) {
- if (ContentType && !request->Endpoint->CompressContentTypes.empty()) {
- TStringBuf contentType = ContentType.Before(';');
- Trim(contentType, ' ');
- if (Count(request->Endpoint->CompressContentTypes, contentType) != 0) {
- if (response->EnableCompression()) {
- headers.Erase("Content-Length"); // we will need new length after compression
- }
- }
- }
- response->Set(headers);
- response->SetBody(Body);
- } else {
- response->Set(headers);
- if (!response->ContentLength) {
- response->Set<&THttpResponse::ContentLength>("0");
- }
- }
- return response;
-}
-
-
-THttpOutgoingResponsePtr THttpIncomingResponse::Reverse(THttpIncomingRequestPtr request) {
- THttpOutgoingResponsePtr response = new THttpOutgoingResponse(request);
- response->Assign(Data(), Size());
- response->Reparse();
- return response;
-}
-
-THttpOutgoingRequest::THttpOutgoingRequest(TStringBuf method, TStringBuf scheme, TStringBuf host, TStringBuf uri, TStringBuf protocol, TStringBuf version) {
- Secure = (scheme == "https");
- TString urie = UrlEscapeRet(uri);
- InitRequest(method, urie, protocol, version);
- if (host) {
- Set<&THttpRequest::Host>(host);
- }
-}
-
-THttpOutgoingRequest::THttpOutgoingRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version) {
- TStringBuf scheme, host, uri;
- if (!CrackURL(url, scheme, host, uri)) {
- Y_ABORT("Invalid URL specified");
- }
- if (!scheme.empty() && scheme != "http" && scheme != "https") {
- Y_ABORT("Invalid URL specified");
- }
- Secure = (scheme == "https");
- TString urie = UrlEscapeRet(uri);
- InitRequest(method, urie, protocol, version);
- if (host) {
- Set<&THttpRequest::Host>(host);
- }
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestString(const TString& data) {
- THttpOutgoingRequestPtr request = new THttpOutgoingRequest();
- request->Assign(data.data(), data.size());
- request->Reparse();
- return request;
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestGet(TStringBuf url) {
- return CreateRequest("GET", url);
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestGet(TStringBuf host, TStringBuf uri) {
- return CreateHttpRequest("GET", host, uri);
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestPost(TStringBuf url, TStringBuf contentType, TStringBuf body) {
- return CreateRequest("POST", url, contentType, body);
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequestPost(TStringBuf host, TStringBuf uri, TStringBuf contentType, TStringBuf body) {
- return CreateHttpRequest("POST", host, uri, contentType, body);
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateRequest(TStringBuf method, TStringBuf url, TStringBuf contentType, TStringBuf body) {
- THttpOutgoingRequestPtr request = new THttpOutgoingRequest(method, url, "HTTP", "1.1");
- request->Set<&THttpRequest::Accept>("*/*");
- if (!contentType.empty()) {
- request->Set<&THttpRequest::ContentType>(contentType);
- request->Set<&THttpRequest::Body>(body);
- }
- return request;
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::CreateHttpRequest(TStringBuf method, TStringBuf host, TStringBuf uri, TStringBuf contentType, TStringBuf body) {
- THttpOutgoingRequestPtr request = new THttpOutgoingRequest(method, "http", host, uri, "HTTP", "1.1");
- request->Set<&THttpRequest::Accept>("*/*");
- if (!contentType.empty()) {
- request->Set<&THttpRequest::ContentType>(contentType);
- request->Set<&THttpRequest::Body>(body);
- }
- return request;
-}
-
-THttpOutgoingRequestPtr THttpOutgoingRequest::Duplicate() {
- THttpOutgoingRequestPtr request = new THttpOutgoingRequest(*this);
- request->Reparse();
- return request;
-}
-
-THttpOutgoingResponse::THttpOutgoingResponse(THttpIncomingRequestPtr request)
- : Request(request)
-{}
-
-THttpOutgoingResponse::THttpOutgoingResponse(THttpIncomingRequestPtr request, TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message)
- : Request(request)
-{
- InitResponse(protocol, version, status, message);
-}
-
-const size_t THttpConfig::BUFFER_MIN_STEP;
-const TDuration THttpConfig::CONNECTION_TIMEOUT;
-
-TUrlParameters::TUrlParameters(TStringBuf url) {
- TStringBuf base;
- TStringBuf params;
- if (url.TrySplit('?', base, params)) {
- for (TStringBuf param = params.NextTok('&'); !param.empty(); param = params.NextTok('&')) {
- TStringBuf name = param.NextTok('=');
- Parameters[name] = param;
- }
- }
-}
-
-TString TUrlParameters::operator [](TStringBuf name) const {
- TString value(Get(name));
- CGIUnescape(value);
- return value;
-}
-
-bool TUrlParameters::Has(TStringBuf name) const {
- return Parameters.count(name) != 0;
-}
-
-TStringBuf TUrlParameters::Get(TStringBuf name) const {
- auto it = Parameters.find(name);
- if (it != Parameters.end()) {
- return it->second;
- }
- return TStringBuf();
-}
-
-TString TUrlParameters::Render() const {
- TStringBuilder parameters;
- for (const std::pair<TStringBuf, TStringBuf> parameter : Parameters) {
- if (parameters.empty()) {
- parameters << '?';
- } else {
- parameters << '&';
- }
- parameters << parameter.first;
- parameters << '=';
- parameters << parameter.second;
- }
- return parameters;
-}
-
-TCookies::TCookies(TStringBuf cookie) {
- for (TStringBuf param = cookie.NextTok(';'); !param.empty(); param = cookie.NextTok(';')) {
- param.SkipPrefix(" ");
- TStringBuf name = param.NextTok('=');
- Cookies[name] = param;
- }
-}
-
-TStringBuf TCookies::operator [](TStringBuf name) const {
- return Get(name);
-}
-
-bool TCookies::Has(TStringBuf name) const {
- return Cookies.count(name) != 0;
-}
-
-TStringBuf TCookies::Get(TStringBuf name) const {
- auto it = Cookies.find(name);
- if (it != Cookies.end()) {
- return it->second;
- }
- return TStringBuf();
-}
-
-TString TCookies::Render() const {
- TStringBuilder cookies;
- for (const std::pair<TStringBuf, TStringBuf> cookie : Cookies) {
- if (!cookies.empty()) {
- cookies << ' ';
- }
- cookies << cookie.first;
- cookies << '=';
- cookies << cookie.second;
- cookies << ';';
- }
- return cookies;
-}
-
-TCookiesBuilder::TCookiesBuilder()
- :TCookies(TStringBuf())
-{}
-
-void TCookiesBuilder::Set(TStringBuf name, TStringBuf data) {
- Data.emplace_back(name, data);
- Cookies[Data.back().first] = Data.back().second;
-}
-
-THeaders::THeaders(TStringBuf headers) {
- Parse(headers);
-}
-
-size_t THeaders::Parse(TStringBuf headers) {
- auto start = headers.begin();
- for (TStringBuf param = headers.NextTok("\r\n"); !param.empty(); param = headers.NextTok("\r\n")) {
- TStringBuf name = param.NextTok(":");
- param.SkipPrefix(" ");
- Headers[name] = param;
- }
- return headers.begin() - start;
-}
-
-const TStringBuf THeaders::operator [](TStringBuf name) const {
- return Get(name);
-}
-
-bool THeaders::Has(TStringBuf name) const {
- return Headers.count(name) != 0;
-}
-
-TStringBuf THeaders::Get(TStringBuf name) const {
- auto it = Headers.find(name);
- if (it != Headers.end()) {
- return it->second;
- }
- return TStringBuf();
-}
-
-TString THeaders::Render() const {
- TStringBuilder headers;
- for (const std::pair<TStringBuf, TStringBuf> header : Headers) {
- headers << header.first;
- headers << ": ";
- headers << header.second;
- headers << "\r\n";
- }
- return headers;
-}
-
-THeadersBuilder::THeadersBuilder()
- : THeaders(TStringBuf())
-{}
-
-THeadersBuilder::THeadersBuilder(TStringBuf headers)
- : THeaders(headers)
-{}
-
-THeadersBuilder::THeadersBuilder(const THeadersBuilder& builder) {
- for (const auto& pr : builder.Headers) {
- Set(pr.first, pr.second);
- }
-}
-
-void THeadersBuilder::Set(TStringBuf name, TStringBuf data) {
- Data.emplace_back(name, data);
- Headers[Data.back().first] = Data.back().second;
-}
-
-void THeadersBuilder::Erase(TStringBuf name) {
- Headers.erase(name);
-}
-
-}
diff --git a/library/cpp/actors/http/http.h b/library/cpp/actors/http/http.h
deleted file mode 100644
index d96ab062e8..0000000000
--- a/library/cpp/actors/http/http.h
+++ /dev/null
@@ -1,877 +0,0 @@
-#pragma once
-#include <util/datetime/base.h>
-#include <util/string/builder.h>
-#include <util/system/thread.h>
-#include <util/system/hp_timer.h>
-#include <util/generic/hash_set.h>
-#include <util/generic/buffer.h>
-#include <util/generic/intrlist.h>
-#include "http_config.h"
-
-// TODO(xenoxeno): hide in implementation
-template <typename Type>
-struct THash<TIntrusivePtr<Type>> {
- size_t operator ()(const TIntrusivePtr<Type>& ptr) const { return reinterpret_cast<size_t>(ptr.Get()); }
-};
-
-template<>
-inline void Out<NHttp::THttpConfig::SocketAddressType>(IOutputStream& o, const NHttp::THttpConfig::SocketAddressType& x) {
- o << x->ToString();
-}
-
-namespace NHttp {
-
-bool IsIPv6(const TString& host);
-bool IsIPv4(const TString& host);
-bool CrackURL(TStringBuf url, TStringBuf& scheme, TStringBuf& host, TStringBuf& uri);
-void CrackAddress(const TString& address, TString& hostname, TIpPort& port);
-void TrimBegin(TStringBuf& target, char delim);
-void TrimEnd(TStringBuf& target, char delim);
-void Trim(TStringBuf& target, char delim);
-void TrimEnd(TString& target, char delim);
-TString CompressDeflate(TStringBuf source);
-TString DecompressDeflate(TStringBuf source);
-
-struct TLessNoCase {
- bool operator()(TStringBuf l, TStringBuf r) const {
- auto ll = l.length();
- auto rl = r.length();
- if (ll != rl) {
- return ll < rl;
- }
- return strnicmp(l.data(), r.data(), ll) < 0;
- }
-};
-
-struct TEqNoCase {
- bool operator()(TStringBuf l, TStringBuf r) const {
- auto ll = l.length();
- auto rl = r.length();
- if (ll != rl) {
- return false;
- }
- return strnicmp(l.data(), r.data(), ll) == 0;
- }
-};
-
-struct TSensors {
- TString Direction;
- TString Host;
- TString Url;
- TString Status;
- TDuration Time;
-
- TSensors(
- TStringBuf direction,
- TStringBuf host,
- TStringBuf url,
- TStringBuf status,
- TDuration time)
- : Direction(direction)
- , Host(host)
- , Url(url)
- , Status(status)
- , Time(time)
- {}
-};
-
-struct TUrlParameters {
- THashMap<TStringBuf, TStringBuf> Parameters;
-
- TUrlParameters(TStringBuf url);
- TString operator [](TStringBuf name) const;
- bool Has(TStringBuf name) const;
- TStringBuf Get(TStringBuf name) const; // raw
- TString Render() const;
-};
-
-struct TCookies {
- THashMap<TStringBuf, TStringBuf> Cookies;
-
- TCookies(TStringBuf cookie);
- TCookies(const TCookies&) = delete;
- TStringBuf operator [](TStringBuf name) const;
- bool Has(TStringBuf name) const;
- TStringBuf Get(TStringBuf name) const; // raw
- TString Render() const;
-};
-
-struct TCookiesBuilder : TCookies {
- TDeque<std::pair<TString, TString>> Data;
-
- TCookiesBuilder();
- void Set(TStringBuf name, TStringBuf data);
-};
-
-struct THeaders {
- TMap<TStringBuf, TStringBuf, TLessNoCase> Headers;
-
- THeaders() = default;
- THeaders(TStringBuf headers);
- THeaders(const THeaders&) = delete;
- const TStringBuf operator [](TStringBuf name) const;
- bool Has(TStringBuf name) const;
- TStringBuf Get(TStringBuf name) const; // raw
- size_t Parse(TStringBuf headers);
- TString Render() const;
-};
-
-struct THeadersBuilder : THeaders {
- TDeque<std::pair<TString, TString>> Data;
-
- THeadersBuilder();
- THeadersBuilder(TStringBuf headers);
- THeadersBuilder(const THeadersBuilder& builder);
- void Set(TStringBuf name, TStringBuf data);
- void Erase(TStringBuf name);
-};
-
-class TSocketBuffer : public TBuffer, public THttpConfig {
-public:
- TSocketBuffer()
- : TBuffer(BUFFER_SIZE)
- {}
-
- bool EnsureEnoughSpaceAvailable(size_t need) {
- size_t avail = Avail();
- if (avail < need) {
- Reserve(Capacity() + std::max(need, BUFFER_MIN_STEP));
- return false;
- }
- return true;
- }
-
- // non-destructive variant of AsString
- TString AsString() const {
- return TString(Data(), Size());
- }
-};
-
-class THttpRequest {
-public:
- TStringBuf Method;
- TStringBuf URL;
- TStringBuf Protocol;
- TStringBuf Version;
- TStringBuf Headers;
-
- TStringBuf Host;
- TStringBuf Accept;
- TStringBuf Connection;
- TStringBuf ContentType;
- TStringBuf ContentLength;
- TStringBuf AcceptEncoding;
- TStringBuf TransferEncoding;
-
- TStringBuf Body;
-
- static const TMap<TStringBuf, TStringBuf THttpRequest::*, TLessNoCase> HeadersLocation;
-
- template <TStringBuf THttpRequest::* Header>
- static TStringBuf GetName();
- void Clear();
-};
-
-class THttpResponse {
-public:
- TStringBuf Protocol;
- TStringBuf Version;
- TStringBuf Status;
- TStringBuf Message;
- TStringBuf Headers;
-
- TStringBuf Connection;
- TStringBuf ContentType;
- TStringBuf ContentLength;
- TStringBuf TransferEncoding;
- TStringBuf LastModified;
- TStringBuf ContentEncoding;
-
- TStringBuf Body;
-
- static const TMap<TStringBuf, TStringBuf THttpResponse::*, TLessNoCase> HeadersLocation;
-
- template <TStringBuf THttpResponse::* Header>
- static TStringBuf GetName();
- void Clear();
-};
-
-template <typename HeaderType, typename BufferType>
-class THttpParser : public HeaderType, public BufferType {
-public:
- enum class EParseStage : ui8 {
- Method,
- URL,
- Protocol,
- Version,
- Status,
- Message,
- Header,
- Body,
- ChunkLength,
- ChunkData,
- Done,
- Error,
- };
-
- static constexpr size_t MaxMethodSize = 8;
- static constexpr size_t MaxURLSize = 2048;
- static constexpr size_t MaxProtocolSize = 4;
- static constexpr size_t MaxVersionSize = 4;
- static constexpr size_t MaxStatusSize = 3;
- static constexpr size_t MaxMessageSize = 1024;
- static constexpr size_t MaxHeaderSize = 8192;
- static constexpr size_t MaxChunkLengthSize = 8;
- static constexpr size_t MaxChunkSize = 256 * 1024 * 1024;
- static constexpr size_t MaxChunkContentSize = 1 * 1024 * 1024 * 1024;
-
- EParseStage Stage;
- EParseStage LastSuccessStage;
- TStringBuf Line;
- TStringBuf& Header = Line;
- size_t ChunkLength = 0;
- size_t ContentSize = 0;
- TString Content; // body storage
- std::optional<size_t> TotalSize;
-
- THttpParser(const THttpParser& src)
- : HeaderType(src)
- , BufferType(src)
- , Stage(src.Stage)
- , LastSuccessStage(src.LastSuccessStage)
- , Line()
- , Header(Line)
- , ChunkLength(src.ChunkLength)
- , ContentSize(src.ContentSize)
- , Content(src.Content)
- {}
-
- template <typename StringType>
- bool ProcessData(StringType& target, TStringBuf& source, char delim, size_t maxLen) {
- TStringBuf maxSource(source.substr(0, maxLen + 1 - target.size()));
- size_t pos = maxSource.find(delim);
- target += maxSource.substr(0, pos);
- source.Skip(pos);
- if (target.size() > maxLen) {
- Stage = EParseStage::Error;
- return false;
- }
- if (!source.empty() && *source.begin() == delim) {
- source.Skip(1);
- }
- return pos != TStringBuf::npos;
- }
-
- template <typename StringType>
- bool ProcessData(StringType& target, TStringBuf& source, TStringBuf delim, size_t maxLen) {
- if (delim.empty()) {
- return false;
- }
- if (delim.size() == 1) {
- return ProcessData(target, source, delim[0], maxLen);
- }
- if (ProcessData(target, source, delim.back(), maxLen + 1)) {
- for (signed i = delim.size() - 2; i >= 0; --i) {
- TrimEnd(target, delim[i]);
- }
- return true;
- }
- return false;
- }
-
- template <typename StringType>
- bool ProcessData(StringType& target, TStringBuf& source, size_t size) {
- TStringBuf maxSource(source.substr(0, size - target.size()));
- target += maxSource;
- source.Skip(maxSource.size());
- if (target.size() > size && !source.empty()) {
- Stage = EParseStage::Error;
- return false;
- }
- return target.size() == size;
- }
-
- void ProcessHeader(TStringBuf& header) {
- TStringBuf name = header.NextTok(':');
- TrimBegin(name, ' ');
- TStringBuf value = header;
- Trim(value, ' ');
- auto cit = HeaderType::HeadersLocation.find(name);
- if (cit != HeaderType::HeadersLocation.end()) {
- this->*cit->second = value;
- }
- header.Clear();
- }
-
- size_t ParseHex(TStringBuf value) {
- size_t result = 0;
- for (char ch : value) {
- if (ch >= '0' && ch <= '9') {
- result *= 16;
- result += ch - '0';
- } else if (ch >= 'a' && ch <= 'f') {
- result *= 16;
- result += 10 + ch - 'a';
- } else if (ch >= 'A' && ch <= 'F') {
- result *= 16;
- result += 10 + ch - 'A';
- } else if (ch == ';') {
- break;
- } else if (isspace(ch)) {
- continue;
- } else {
- Stage = EParseStage::Error;
- return 0;
- }
- }
- return result;
- }
-
- void Advance(size_t len);
- void ConnectionClosed();
-
- size_t GetBodySizeFromTotalSize() const {
- return TotalSize.value() - (HeaderType::Headers.end() - BufferType::Data());
- }
-
- void Clear() {
- BufferType::Clear();
- HeaderType::Clear();
- Stage = GetInitialStage();
- Line.Clear();
- Content.clear();
- }
-
- bool IsReady() const {
- return Stage == EParseStage::Done;
- }
-
- bool IsError() const {
- return Stage == EParseStage::Error;
- }
-
- TStringBuf GetErrorText() const {
- switch (LastSuccessStage) {
- case EParseStage::Method:
- return "Invalid http method";
- case EParseStage::URL:
- return "Invalid url";
- case EParseStage::Protocol:
- return "Invalid http protocol";
- case EParseStage::Version:
- return "Invalid http version";
- case EParseStage::Status:
- return "Invalid http status";
- case EParseStage::Message:
- return "Invalid http message";
- case EParseStage::Header:
- return "Invalid http header";
- case EParseStage::Body:
- return "Invalid content body";
- case EParseStage::ChunkLength:
- case EParseStage::ChunkData:
- return "Broken chunked data";
- case EParseStage::Done:
- return "Everything is fine";
- case EParseStage::Error:
- return "Error on error"; // wat? ...because we don't want to include default label here
- }
- }
-
- bool IsDone() const {
- return IsReady() || IsError();
- }
-
- bool HaveBody() const;
-
- bool EnsureEnoughSpaceAvailable(size_t need = BufferType::BUFFER_MIN_STEP) {
- bool result = BufferType::EnsureEnoughSpaceAvailable(need);
- if (!result && !BufferType::Empty()) {
- Reparse();
- }
- return true;
- }
-
- void Reparse() {
- size_t size = BufferType::Size();
- Clear();
- Advance(size);
- }
-
- TStringBuf GetRawData() const {
- return TStringBuf(BufferType::Data(), BufferType::Size());
- }
-
- TString GetObfuscatedData() const {
- THeaders headers(HeaderType::Headers);
- TStringBuf authorization(headers["Authorization"]);
- TStringBuf cookie(headers["Cookie"]);
- TStringBuf x_ydb_auth_ticket(headers["x-ydb-auth-ticket"]);
- TStringBuf x_yacloud_subjecttoken(headers["x-yacloud-subjecttoken"]);
- TString data(GetRawData());
- if (!authorization.empty()) {
- auto pos = data.find(authorization);
- if (pos != TString::npos) {
- data.replace(pos, authorization.size(), TString("<obfuscated>"));
- }
- }
- if (!cookie.empty()) {
- auto pos = data.find(cookie);
- if (pos != TString::npos) {
- data.replace(pos, cookie.size(), TString("<obfuscated>"));
- }
- }
- if (!x_ydb_auth_ticket.empty()) {
- auto pos = data.find(x_ydb_auth_ticket);
- if (pos != TString::npos) {
- data.replace(pos, x_ydb_auth_ticket.size(), TString("<obfuscated>"));
- }
- }
- if (!x_yacloud_subjecttoken.empty()) {
- auto pos = data.find(x_yacloud_subjecttoken);
- if (pos != TString::npos) {
- data.replace(pos, x_yacloud_subjecttoken.size(), TString("<obfuscated>"));
- }
- }
- return data;
- }
-
- static EParseStage GetInitialStage();
-
- THttpParser()
- : Stage(GetInitialStage())
- , LastSuccessStage(Stage)
- {}
-
- THttpParser(TStringBuf data)
- : Stage(GetInitialStage())
- , LastSuccessStage(Stage)
- {
- BufferType::Assign(data.data(), data.size());
- BufferType::Clear(); // reset position to 0
- TotalSize = data.size();
- Advance(data.size());
- }
-};
-
-template <typename HeaderType, typename BufferType>
-class THttpRenderer : public HeaderType, public BufferType {
-public:
- enum class ERenderStage {
- Init,
- Header,
- Body,
- Done,
- Error,
- };
-
- ERenderStage Stage = ERenderStage::Init;
- TString Content; // body storage
-
- //THttpRenderer(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version); // request
- void InitRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version) {
- Y_DEBUG_ABORT_UNLESS(Stage == ERenderStage::Init);
- AppendParsedValue<&THttpRequest::Method>(method);
- Append(' ');
- AppendParsedValue<&THttpRequest::URL>(url);
- Append(' ');
- AppendParsedValue<&THttpRequest::Protocol>(protocol);
- Append('/');
- AppendParsedValue<&THttpRequest::Version>(version);
- Append("\r\n");
- Stage = ERenderStage::Header;
- HeaderType::Headers = TStringBuf(BufferType::Pos(), size_t(0));
- }
-
- //THttpRenderer(TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message); // response
- void InitResponse(TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message) {
- Y_DEBUG_ABORT_UNLESS(Stage == ERenderStage::Init);
- AppendParsedValue<&THttpResponse::Protocol>(protocol);
- Append('/');
- AppendParsedValue<&THttpResponse::Version>(version);
- Append(' ');
- AppendParsedValue<&THttpResponse::Status>(status);
- Append(' ');
- AppendParsedValue<&THttpResponse::Message>(message);
- Append("\r\n");
- Stage = ERenderStage::Header;
- HeaderType::Headers = TStringBuf(BufferType::Pos(), size_t(0));
- }
-
- void Append(TStringBuf text) {
- EnsureEnoughSpaceAvailable(text.size());
- BufferType::Append(text.data(), text.size());
- }
-
- void Append(char c) {
- EnsureEnoughSpaceAvailable(sizeof(c));
- BufferType::Append(c);
- }
-
- template <TStringBuf HeaderType::* string>
- void AppendParsedValue(TStringBuf value) {
- Append(value);
- static_cast<HeaderType*>(this)->*string = TStringBuf(BufferType::Pos() - value.size(), value.size());
- }
-
- template <TStringBuf HeaderType::* name>
- void Set(TStringBuf value) {
- Y_DEBUG_ABORT_UNLESS(Stage == ERenderStage::Header);
- Append(HeaderType::template GetName<name>());
- Append(": ");
- AppendParsedValue<name>(value);
- Append("\r\n");
- HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
- }
-
- void Set(TStringBuf name, TStringBuf value) {
- Y_DEBUG_ABORT_UNLESS(Stage == ERenderStage::Header);
- Append(name);
- Append(": ");
- auto data = BufferType::Pos();
- Append(value);
- auto cit = HeaderType::HeadersLocation.find(name);
- if (cit != HeaderType::HeadersLocation.end()) {
- (this->*cit->second) = TStringBuf(data, BufferType::Pos());
- }
- Append("\r\n");
- HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
- }
-
- void Set(const THeaders& headers) {
- Y_DEBUG_ABORT_UNLESS(Stage == ERenderStage::Header);
- for (const auto& [name, value] : headers.Headers) {
- Set(name, value);
- }
- HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
- }
-
- static constexpr TStringBuf ALLOWED_CONTENT_ENCODINGS[] = {"deflate"};
-
- void SetContentEncoding(TStringBuf contentEncoding) {
- Y_DEBUG_ABORT_UNLESS(Stage == ERenderStage::Header);
- if (Count(ALLOWED_CONTENT_ENCODINGS, contentEncoding) != 0) {
- Set("Content-Encoding", contentEncoding);
- }
- }
-
- void FinishHeader() {
- Append("\r\n");
- HeaderType::Headers = TStringBuf(HeaderType::Headers.Data(), BufferType::Pos() - HeaderType::Headers.Data());
- Stage = ERenderStage::Body;
- }
-
- void SetBody(TStringBuf body) {
- Y_DEBUG_ABORT_UNLESS(Stage == ERenderStage::Header);
- if (HeaderType::ContentLength.empty()) {
- Set<&HeaderType::ContentLength>(ToString(body.size()));
- }
- FinishHeader();
- AppendParsedValue<&HeaderType::Body>(body);
- Stage = ERenderStage::Done;
- }
-
- void FinishBody() {
- Stage = ERenderStage::Done;
- }
-
- bool IsDone() const {
- return Stage == ERenderStage::Done;
- }
-
- void Finish() {
- switch (Stage) {
- case ERenderStage::Header:
- FinishHeader();
- FinishBody();
- break;
- case ERenderStage::Body:
- FinishBody();
- break;
- default:
- break;
- }
- }
-
- bool EnsureEnoughSpaceAvailable(size_t need = BufferType::BUFFER_MIN_STEP) {
- bool result = BufferType::EnsureEnoughSpaceAvailable(need);
- if (!result && !BufferType::Empty()) {
- Reparse();
- }
- return true;
- }
-
- void Clear() {
- BufferType::Clear();
- HeaderType::Clear();
- }
-
- void Reparse() {
- // move-magic
- size_t size = BufferType::Size();
- THttpParser<HeaderType, BufferType> parser;
- // move the buffer to parser
- static_cast<BufferType&>(parser) = std::move(static_cast<BufferType&>(*this));
- // reparse
- parser.Clear();
- parser.Advance(size);
- // move buffer and result back
- bool needReassignBody = (parser.Body.data() == parser.Content.data());
- static_cast<HeaderType&>(*this) = std::move(static_cast<HeaderType&>(parser));
- static_cast<BufferType&>(*this) = std::move(static_cast<BufferType&>(parser));
- if (needReassignBody) {
- Content = std::move(parser.Content);
- HeaderType::Body = Content;
- }
- switch (parser.Stage) {
- case THttpParser<HeaderType, BufferType>::EParseStage::Method:
- case THttpParser<HeaderType, BufferType>::EParseStage::URL:
- case THttpParser<HeaderType, BufferType>::EParseStage::Protocol:
- case THttpParser<HeaderType, BufferType>::EParseStage::Version:
- case THttpParser<HeaderType, BufferType>::EParseStage::Status:
- case THttpParser<HeaderType, BufferType>::EParseStage::Message:
- Stage = ERenderStage::Init;
- break;
- case THttpParser<HeaderType, BufferType>::EParseStage::Header:
- Stage = ERenderStage::Header;
- break;
- case THttpParser<HeaderType, BufferType>::EParseStage::Body:
- case THttpParser<HeaderType, BufferType>::EParseStage::ChunkLength:
- case THttpParser<HeaderType, BufferType>::EParseStage::ChunkData:
- Stage = ERenderStage::Body;
- break;
- case THttpParser<HeaderType, BufferType>::EParseStage::Done:
- Stage = ERenderStage::Done;
- break;
- case THttpParser<HeaderType, BufferType>::EParseStage::Error:
- Stage = ERenderStage::Error;
- break;
- }
- Y_ABORT_UNLESS(size == BufferType::Size());
- }
-
- TStringBuf GetRawData() const {
- return TStringBuf(BufferType::Data(), BufferType::Size());
- }
-};
-
-template <>
-template <>
-inline void THttpRenderer<THttpResponse, TSocketBuffer>::Set<&THttpResponse::Body>(TStringBuf value) {
- SetBody(value);
-}
-
-template <>
-template <>
-inline void THttpRenderer<THttpRequest, TSocketBuffer>::Set<&THttpRequest::Body>(TStringBuf value) {
- SetBody(value);
-}
-
-template <>
-template <>
-inline void THttpRenderer<THttpResponse, TSocketBuffer>::Set<&THttpResponse::ContentEncoding>(TStringBuf value) {
- SetContentEncoding(value);
-}
-
-struct THttpEndpointInfo {
- TString WorkerName;
- bool Secure = false;
- const std::vector<TString> CompressContentTypes; // content types, which will be automatically compressed on response
-
- THttpEndpointInfo() = default;
-
-protected:
- THttpEndpointInfo(std::vector<TString> compressContentTypes)
- : CompressContentTypes(std::move(compressContentTypes))
- {}
-};
-
-class THttpIncomingRequest;
-using THttpIncomingRequestPtr = TIntrusivePtr<THttpIncomingRequest>;
-
-class THttpOutgoingResponse;
-using THttpOutgoingResponsePtr = TIntrusivePtr<THttpOutgoingResponse>;
-
-class THttpIncomingRequest :
- public THttpParser<THttpRequest, TSocketBuffer>,
- public TRefCounted<THttpIncomingRequest, TAtomicCounter> {
-public:
- std::shared_ptr<THttpEndpointInfo> Endpoint;
- THttpConfig::SocketAddressType Address;
- THPTimer Timer;
-
- THttpIncomingRequest()
- : Endpoint(std::make_shared<THttpEndpointInfo>())
- {}
-
- THttpIncomingRequest(std::shared_ptr<THttpEndpointInfo> endpoint, const THttpConfig::SocketAddressType& address)
- : Endpoint(std::move(endpoint))
- , Address(address)
- {}
-
- THttpIncomingRequest(TStringBuf content, std::shared_ptr<THttpEndpointInfo> endpoint, const THttpConfig::SocketAddressType& address)
- : THttpParser(content)
- , Endpoint(std::move(endpoint))
- , Address(address)
- {}
-
- bool IsConnectionClose() const {
- if (Connection.empty()) {
- return Version == "1.0";
- } else {
- return TEqNoCase()(Connection, "close");
- }
- }
-
- TStringBuf GetConnection() const {
- if (!Connection.empty()) {
- if (TEqNoCase()(Connection, "keep-alive")) {
- return "keep-alive";
- }
- if (TEqNoCase()(Connection, "close")) {
- return "close";
- }
- }
- return Version == "1.0" ? "close" : "keep-alive";
- }
-
- THttpOutgoingResponsePtr CreateResponseOK(TStringBuf body, TStringBuf contentType = "text/html", TInstant lastModified = TInstant());
- THttpOutgoingResponsePtr CreateResponseString(TStringBuf data);
- THttpOutgoingResponsePtr CreateResponseBadRequest(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 400
- THttpOutgoingResponsePtr CreateResponseNotFound(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 404
- THttpOutgoingResponsePtr CreateResponseServiceUnavailable(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 503
- THttpOutgoingResponsePtr CreateResponseGatewayTimeout(TStringBuf html = TStringBuf(), TStringBuf contentType = "text/html"); // 504
- THttpOutgoingResponsePtr CreateResponse(TStringBuf status, TStringBuf message);
- THttpOutgoingResponsePtr CreateResponse(TStringBuf status, TStringBuf message, const THeaders& headers);
- THttpOutgoingResponsePtr CreateResponse(TStringBuf status, TStringBuf message, const THeaders& headers, TStringBuf body);
- THttpOutgoingResponsePtr CreateResponse(
- TStringBuf status,
- TStringBuf message,
- TStringBuf contentType,
- TStringBuf body = TStringBuf(),
- TInstant lastModified = TInstant());
-
- THttpOutgoingResponsePtr CreateIncompleteResponse(TStringBuf status, TStringBuf message, const THeaders& headers = {});
- THttpOutgoingResponsePtr CreateIncompleteResponse(TStringBuf status, TStringBuf message, const THeaders& headers, TStringBuf body);
-
- THttpIncomingRequestPtr Duplicate();
-
-private:
- THttpOutgoingResponsePtr ConstructResponse(TStringBuf status, TStringBuf message);
- void FinishResponse(THttpOutgoingResponsePtr& response, TStringBuf body = TStringBuf());
-};
-
-class THttpIncomingResponse;
-using THttpIncomingResponsePtr = TIntrusivePtr<THttpIncomingResponse>;
-
-class THttpOutgoingRequest;
-using THttpOutgoingRequestPtr = TIntrusivePtr<THttpOutgoingRequest>;
-
-class THttpIncomingResponse :
- public THttpParser<THttpResponse, TSocketBuffer>,
- public TRefCounted<THttpIncomingResponse, TAtomicCounter> {
-public:
- THttpIncomingResponse(THttpOutgoingRequestPtr request);
-
- THttpOutgoingRequestPtr GetRequest() const {
- return Request;
- }
-
- THttpIncomingResponsePtr Duplicate(THttpOutgoingRequestPtr request);
- THttpOutgoingResponsePtr Reverse(THttpIncomingRequestPtr request);
-
-protected:
- THttpOutgoingRequestPtr Request;
-};
-
-class THttpOutgoingRequest :
- public THttpRenderer<THttpRequest, TSocketBuffer>,
- public TRefCounted<THttpOutgoingRequest, TAtomicCounter> {
-public:
- THPTimer Timer;
- bool Secure = false;
-
- THttpOutgoingRequest() = default;
- THttpOutgoingRequest(TStringBuf method, TStringBuf url, TStringBuf protocol, TStringBuf version);
- THttpOutgoingRequest(TStringBuf method, TStringBuf scheme, TStringBuf host, TStringBuf uri, TStringBuf protocol, TStringBuf version);
- static THttpOutgoingRequestPtr CreateRequestString(TStringBuf data);
- static THttpOutgoingRequestPtr CreateRequestString(const TString& data);
- static THttpOutgoingRequestPtr CreateRequestGet(TStringBuf url);
- static THttpOutgoingRequestPtr CreateRequestGet(TStringBuf host, TStringBuf uri); // http only
- static THttpOutgoingRequestPtr CreateRequestPost(TStringBuf url, TStringBuf contentType = {}, TStringBuf body = {});
- static THttpOutgoingRequestPtr CreateRequestPost(TStringBuf host, TStringBuf uri, TStringBuf contentType, TStringBuf body); // http only
- static THttpOutgoingRequestPtr CreateRequest(TStringBuf method, TStringBuf url, TStringBuf contentType = TStringBuf(), TStringBuf body = TStringBuf());
- static THttpOutgoingRequestPtr CreateHttpRequest(TStringBuf method, TStringBuf host, TStringBuf uri, TStringBuf contentType = TStringBuf(), TStringBuf body = TStringBuf());
- THttpOutgoingRequestPtr Duplicate();
-};
-
-class THttpOutgoingResponse :
- public THttpRenderer<THttpResponse, TSocketBuffer>,
- public TRefCounted<THttpOutgoingResponse, TAtomicCounter> {
-public:
- THttpOutgoingResponse(THttpIncomingRequestPtr request);
- THttpOutgoingResponse(THttpIncomingRequestPtr request, TStringBuf protocol, TStringBuf version, TStringBuf status, TStringBuf message);
-
- bool IsConnectionClose() const {
- if (!Connection.empty()) {
- return TEqNoCase()(Connection, "close");
- } else {
- return Request->IsConnectionClose();
- }
- }
-
- bool IsNeedBody() const {
- return GetRequest()->Method != "HEAD" && Status != "204";
- }
-
- bool EnableCompression() {
- TStringBuf acceptEncoding = Request->AcceptEncoding;
- std::vector<TStringBuf> encodings;
- TStringBuf encoding;
- while (acceptEncoding.NextTok(',', encoding)) {
- Trim(encoding, ' ');
- if (Count(ALLOWED_CONTENT_ENCODINGS, encoding) != 0) {
- encodings.push_back(encoding);
- }
- }
- if (!encodings.empty()) {
- // TODO: prioritize encodings
- SetContentEncoding(encodings.front());
- return true;
- }
- return false;
- }
-
- void SetBody(TStringBuf body) {
- if (ContentEncoding == "deflate") {
- TString compressedBody = CompressDeflate(body);
- THttpRenderer<THttpResponse, TSocketBuffer>::SetBody(compressedBody);
- Body = Content = body;
- } else {
- THttpRenderer<THttpResponse, TSocketBuffer>::SetBody(body);
- }
- }
-
- void SetBody(const TString& body) {
- if (ContentEncoding == "deflate") {
- TString compressedBody = CompressDeflate(body);
- THttpRenderer<THttpResponse, TSocketBuffer>::SetBody(compressedBody);
- Body = Content = body;
- } else {
- THttpRenderer<THttpResponse, TSocketBuffer>::SetBody(body);
- }
- }
-
- THttpIncomingRequestPtr GetRequest() const {
- return Request;
- }
-
- THttpOutgoingResponsePtr Duplicate(THttpIncomingRequestPtr request);
-
-// it's temporary accessible for cleanup
-//protected:
- THttpIncomingRequestPtr Request;
- std::unique_ptr<TSensors> Sensors;
-};
-
-}
diff --git a/library/cpp/actors/http/http_cache.cpp b/library/cpp/actors/http/http_cache.cpp
deleted file mode 100644
index d2856f70c2..0000000000
--- a/library/cpp/actors/http/http_cache.cpp
+++ /dev/null
@@ -1,608 +0,0 @@
-#include "http.h"
-#include "http_proxy.h"
-#include "http_cache.h"
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/executor_pool_basic.h>
-#include <library/cpp/actors/core/log.h>
-#include <library/cpp/actors/core/scheduler_basic.h>
-#include <library/cpp/actors/http/http.h>
-#include <library/cpp/digest/md5/md5.h>
-#include <util/digest/multi.h>
-#include <util/generic/queue.h>
-#include <util/string/cast.h>
-
-namespace NHttp {
-
-static bool StatusSuccess(const TStringBuf& status) {
- return status.StartsWith("2");
-}
-
-class THttpOutgoingCacheActor : public NActors::TActorBootstrapped<THttpOutgoingCacheActor>, THttpConfig {
-public:
- using TBase = NActors::TActorBootstrapped<THttpOutgoingCacheActor>;
- NActors::TActorId HttpProxyId;
- TGetCachePolicy GetCachePolicy;
- static constexpr TDuration RefreshTimeout = TDuration::Seconds(1);
-
- struct TCacheKey {
- TString Host;
- TString URL;
- TString Headers;
-
- operator size_t() const {
- return MultiHash(Host, URL, Headers);
- }
-
- TString GetId() const {
- return MD5::Calc(Host + ':' + URL + ':' + Headers);
- }
- };
-
- struct TCacheRecord {
- TInstant RefreshTime;
- TInstant DeathTime;
- TCachePolicy CachePolicy;
- NHttp::THttpOutgoingRequestPtr Request;
- NHttp::THttpOutgoingRequestPtr OutgoingRequest;
- TDuration Timeout;
- NHttp::THttpIncomingResponsePtr Response;
- TString Error;
- TVector<NHttp::TEvHttpProxy::TEvHttpOutgoingRequest::TPtr> Waiters;
-
- TCacheRecord(const TCachePolicy cachePolicy)
- : CachePolicy(cachePolicy)
- {}
-
- bool IsValid() const {
- return Response != nullptr || !Error.empty();
- }
-
- void UpdateResponse(NHttp::THttpIncomingResponsePtr response, const TString& error, TInstant now) {
- if (error.empty() || Response == nullptr || !CachePolicy.KeepOnError) {
- Response = response;
- Error = error;
- }
- RefreshTime = now + CachePolicy.TimeToRefresh;
- if (CachePolicy.PaceToRefresh) {
- RefreshTime += TDuration::MilliSeconds(RandomNumber<ui64>() % CachePolicy.PaceToRefresh.MilliSeconds());
- }
- }
-
- TString GetName() const {
- return TStringBuilder() << (Request->Secure ? "https://" : "http://") << Request->Host << Request->URL;
- }
- };
-
- struct TRefreshRecord {
- TCacheKey Key;
- TInstant RefreshTime;
-
- bool operator <(const TRefreshRecord& b) const {
- return RefreshTime > b.RefreshTime;
- }
- };
-
- THashMap<TCacheKey, TCacheRecord> Cache;
- TPriorityQueue<TRefreshRecord> RefreshQueue;
- THashMap<THttpOutgoingRequest*, TCacheKey> OutgoingRequests;
-
- THttpOutgoingCacheActor(const NActors::TActorId& httpProxyId, TGetCachePolicy getCachePolicy)
- : HttpProxyId(httpProxyId)
- , GetCachePolicy(std::move(getCachePolicy))
- {}
-
- static constexpr char ActorName[] = "HTTP_OUT_CACHE_ACTOR";
-
- void Bootstrap(const NActors::TActorContext&) {
- //
- Become(&THttpOutgoingCacheActor::StateWork, RefreshTimeout, new NActors::TEvents::TEvWakeup());
- }
-
- static TString GetCacheHeadersKey(const NHttp::THttpOutgoingRequest* request, const TCachePolicy& policy) {
- TStringBuilder key;
- if (!policy.HeadersToCacheKey.empty()) {
- NHttp::THeaders headers(request->Headers);
- for (const TString& header : policy.HeadersToCacheKey) {
- key << headers[header];
- }
- }
- return key;
- }
-
- static TCacheKey GetCacheKey(const NHttp::THttpOutgoingRequest* request, const TCachePolicy& policy) {
- return { ToString(request->Host), ToString(request->URL), GetCacheHeadersKey(request, policy) };
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvRegisterHandler::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
- NHttp::THttpOutgoingRequestPtr request(event->Get()->Request);
- NHttp::THttpIncomingResponsePtr response(event->Get()->Response);
- auto itRequests = OutgoingRequests.find(request.Get());
- if (itRequests == OutgoingRequests.end()) {
- LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown request " << request->Host << request->URL);
- return;
- }
- auto key = itRequests->second;
- OutgoingRequests.erase(itRequests);
- auto it = Cache.find(key);
- if (it == Cache.end()) {
- LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown cache key " << request->Host << request->URL);
- return;
- }
- TCacheRecord& cacheRecord = it->second;
- cacheRecord.OutgoingRequest.Reset();
- for (auto& waiter : cacheRecord.Waiters) {
- NHttp::THttpIncomingResponsePtr response2;
- TString error2;
- if (response != nullptr) {
- response2 = response->Duplicate(waiter->Get()->Request);
- }
- if (!event->Get()->Error.empty()) {
- error2 = event->Get()->Error;
- }
- ctx.Send(waiter->Sender, new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(waiter->Get()->Request, response2, error2));
- }
- cacheRecord.Waiters.clear();
- TString error;
- if (event->Get()->Error.empty()) {
- if (event->Get()->Response != nullptr && !StatusSuccess(event->Get()->Response->Status)) {
- error = event->Get()->Response->Message;
- }
- } else {
- error = event->Get()->Error;
- }
- if (!error.empty()) {
- LOG_WARN_S(ctx, HttpLog, "Error from " << cacheRecord.GetName() << ": " << error);
- }
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingUpdate " << cacheRecord.GetName());
- cacheRecord.UpdateResponse(response, event->Get()->Error, ctx.Now());
- RefreshQueue.push({it->first, it->second.RefreshTime});
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingSchedule " << cacheRecord.GetName() << " at " << cacheRecord.RefreshTime << " until " << cacheRecord.DeathTime);
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
- const NHttp::THttpOutgoingRequest* request = event->Get()->Request.Get();
- auto policy = GetCachePolicy(request);
- if (policy.TimeToExpire == TDuration()) {
- ctx.Send(event->Forward(HttpProxyId));
- return;
- }
- auto key = GetCacheKey(request, policy);
- auto it = Cache.find(key);
- if (it != Cache.end()) {
- if (it->second.IsValid()) {
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingRespond "
- << it->second.GetName()
- << " ("
- << ((it->second.Response != nullptr) ? ToString(it->second.Response->Size()) : TString("error"))
- << ")");
- NHttp::THttpIncomingResponsePtr response = it->second.Response;
- if (response != nullptr) {
- response = response->Duplicate(event->Get()->Request);
- }
- ctx.Send(event->Sender,
- new NHttp::TEvHttpProxy::TEvHttpIncomingResponse(event->Get()->Request,
- response,
- it->second.Error));
- it->second.DeathTime = ctx.Now() + it->second.CachePolicy.TimeToExpire; // prolong active cache items
- return;
- }
- } else {
- it = Cache.emplace(key, policy).first;
- it->second.Request = event->Get()->Request;
- it->second.Timeout = event->Get()->Timeout;
- it->second.OutgoingRequest = it->second.Request->Duplicate();
- OutgoingRequests[it->second.OutgoingRequest.Get()] = key;
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingInitiate " << it->second.GetName());
- ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(it->second.OutgoingRequest, it->second.Timeout));
- }
- it->second.DeathTime = ctx.Now() + it->second.CachePolicy.TimeToExpire;
- it->second.Waiters.emplace_back(std::move(event));
- }
-
- void HandleRefresh(const NActors::TActorContext& ctx) {
- while (!RefreshQueue.empty() && RefreshQueue.top().RefreshTime <= ctx.Now()) {
- TRefreshRecord rrec = RefreshQueue.top();
- RefreshQueue.pop();
- auto it = Cache.find(rrec.Key);
- if (it != Cache.end()) {
- if (it->second.DeathTime > ctx.Now()) {
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingRefresh " << it->second.GetName());
- it->second.OutgoingRequest = it->second.Request->Duplicate();
- OutgoingRequests[it->second.OutgoingRequest.Get()] = it->first;
- ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(it->second.OutgoingRequest, it->second.Timeout));
- } else {
- LOG_DEBUG_S(ctx, HttpLog, "OutgoingForget " << it->second.GetName());
- if (it->second.OutgoingRequest) {
- OutgoingRequests.erase(it->second.OutgoingRequest.Get());
- }
- Cache.erase(it);
- }
- }
- }
- ctx.Schedule(RefreshTimeout, new NActors::TEvents::TEvWakeup());
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvAddListeningPort, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvRegisterHandler, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse, Handle);
- CFunc(NActors::TEvents::TSystem::Wakeup, HandleRefresh);
- }
- }
-};
-
-const TDuration THttpOutgoingCacheActor::RefreshTimeout;
-
-class THttpIncomingCacheActor : public NActors::TActorBootstrapped<THttpIncomingCacheActor>, THttpConfig {
-public:
- using TBase = NActors::TActorBootstrapped<THttpIncomingCacheActor>;
- NActors::TActorId HttpProxyId;
- TGetCachePolicy GetCachePolicy;
- static constexpr TDuration RefreshTimeout = TDuration::Seconds(1);
- THashMap<TString, TActorId> Handlers;
-
- struct TCacheKey {
- TString Host;
- TString URL;
- TString Headers;
-
- operator size_t() const {
- return MultiHash(Host, URL, Headers);
- }
-
- TString GetId() const {
- return MD5::Calc(Host + ':' + URL + ':' + Headers);
- }
- };
-
- struct TCacheRecord {
- TInstant RefreshTime;
- TInstant DeathTime;
- TCachePolicy CachePolicy;
- TString CacheId;
- NHttp::THttpIncomingRequestPtr Request;
- TDuration Timeout;
- NHttp::THttpOutgoingResponsePtr Response;
- TVector<NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr> Waiters;
- ui32 Retries = 0;
- bool Enqueued = false;
-
- TCacheRecord(const TCachePolicy cachePolicy)
- : CachePolicy(cachePolicy)
- {}
-
- bool IsValid() const {
- return Response != nullptr;
- }
-
- void InitRequest(NHttp::THttpIncomingRequestPtr request) {
- Request = request;
- if (CachePolicy.TimeToExpire) {
- DeathTime = NActors::TlsActivationContext->Now() + CachePolicy.TimeToExpire;
- }
- }
-
- void UpdateResponse(NHttp::THttpOutgoingResponsePtr response, const TString& error, TInstant now) {
- if (error.empty() || !CachePolicy.KeepOnError) {
- Response = response;
- }
- Retries = 0;
- if (CachePolicy.TimeToRefresh) {
- RefreshTime = now + CachePolicy.TimeToRefresh;
- if (CachePolicy.PaceToRefresh) {
- RefreshTime += TDuration::MilliSeconds(RandomNumber<ui64>() % CachePolicy.PaceToRefresh.MilliSeconds());
- }
- }
- }
-
- void UpdateExpireTime() {
- if (CachePolicy.TimeToExpire) {
- DeathTime = NActors::TlsActivationContext->Now() + CachePolicy.TimeToExpire;
- }
- }
-
- TString GetName() const {
- return TStringBuilder() << (Request->Endpoint->Secure ? "https://" : "http://") << Request->Host << Request->URL
- << " (" << CacheId << ")";
- }
- };
-
- struct TRefreshRecord {
- TCacheKey Key;
- TInstant RefreshTime;
-
- bool operator <(const TRefreshRecord& b) const {
- return RefreshTime > b.RefreshTime;
- }
- };
-
- THashMap<TCacheKey, TCacheRecord> Cache;
- TPriorityQueue<TRefreshRecord> RefreshQueue;
- THashMap<THttpIncomingRequest*, TCacheKey> IncomingRequests;
-
- THttpIncomingCacheActor(const NActors::TActorId& httpProxyId, TGetCachePolicy getCachePolicy)
- : HttpProxyId(httpProxyId)
- , GetCachePolicy(std::move(getCachePolicy))
- {}
-
- static constexpr char ActorName[] = "HTTP_IN_CACHE_ACTOR";
-
- void Bootstrap(const NActors::TActorContext&) {
- //
- Become(&THttpIncomingCacheActor::StateWork, RefreshTimeout, new NActors::TEvents::TEvWakeup());
- }
-
- static TString GetCacheHeadersKey(const NHttp::THttpIncomingRequest* request, const TCachePolicy& policy) {
- TStringBuilder key;
- if (!policy.HeadersToCacheKey.empty()) {
- NHttp::THeaders headers(request->Headers);
- for (const TString& header : policy.HeadersToCacheKey) {
- key << headers[header];
- }
- }
- return key;
- }
-
- static TCacheKey GetCacheKey(const NHttp::THttpIncomingRequest* request, const TCachePolicy& policy) {
- return { ToString(request->Host), ToString(request->URL), GetCacheHeadersKey(request, policy) };
- }
-
- TActorId GetRequestHandler(NHttp::THttpIncomingRequestPtr request) {
- TStringBuf url = request->URL.Before('?');
- THashMap<TString, TActorId>::iterator it;
- while (!url.empty()) {
- it = Handlers.find(url);
- if (it != Handlers.end()) {
- return it->second;
- } else {
- if (url.EndsWith('/')) {
- url.Trunc(url.size() - 1);
- }
- size_t pos = url.rfind('/');
- if (pos == TStringBuf::npos) {
- break;
- } else {
- url = url.substr(0, pos + 1);
- }
- }
- }
- return {};
- }
-
- void SendCacheRequest(const TCacheKey& cacheKey, TCacheRecord& cacheRecord, const NActors::TActorContext& ctx) {
- cacheRecord.Request = cacheRecord.Request->Duplicate();
- cacheRecord.Request->AcceptEncoding.Clear(); // disable compression
- IncomingRequests[cacheRecord.Request.Get()] = cacheKey;
- TActorId handler = GetRequestHandler(cacheRecord.Request);
- if (handler) {
- Send(handler, new NHttp::TEvHttpProxy::TEvHttpIncomingRequest(cacheRecord.Request));
- } else {
- LOG_ERROR_S(ctx, HttpLog, "Can't find cache handler for " << cacheRecord.GetName());
- }
- }
-
- void DropCacheRecord(THashMap<TCacheKey, TCacheRecord>::iterator it) {
- if (it->second.Request) {
- IncomingRequests.erase(it->second.Request.Get());
- }
- for (auto& waiter : it->second.Waiters) {
- NHttp::THttpOutgoingResponsePtr response;
- response = waiter->Get()->Request->CreateResponseGatewayTimeout("Timeout", "text/plain");
- Send(waiter->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- }
- Cache.erase(it);
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(HttpProxyId));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvRegisterHandler::TPtr event, const NActors::TActorContext& ctx) {
- Handlers[event->Get()->Path] = event->Get()->Handler;
- ctx.Send(HttpProxyId, new NHttp::TEvHttpProxy::TEvRegisterHandler(event->Get()->Path, ctx.SelfID));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const NActors::TActorContext& ctx) {
- NHttp::THttpIncomingRequestPtr request(event->Get()->Response->GetRequest());
- NHttp::THttpOutgoingResponsePtr response(event->Get()->Response);
- auto itRequests = IncomingRequests.find(request.Get());
- if (itRequests == IncomingRequests.end()) {
- LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown request " << request->Host << request->URL);
- return;
- }
-
- TCacheKey key = itRequests->second;
- auto it = Cache.find(key);
- if (it == Cache.end()) {
- LOG_ERROR_S(ctx, HttpLog, "Cache received response to unknown cache key " << request->Host << request->URL);
- return;
- }
-
- IncomingRequests.erase(itRequests);
- TCacheRecord& cacheRecord = it->second;
- TStringBuf status;
- TString error;
-
- if (event->Get()->Response != nullptr) {
- status = event->Get()->Response->Status;
- if (!StatusSuccess(status)) {
- error = event->Get()->Response->Message;
- }
- }
- if (cacheRecord.CachePolicy.RetriesCount > 0) {
- auto itStatusToRetry = std::find(cacheRecord.CachePolicy.StatusesToRetry.begin(), cacheRecord.CachePolicy.StatusesToRetry.end(), status);
- if (itStatusToRetry != cacheRecord.CachePolicy.StatusesToRetry.end()) {
- if (cacheRecord.Retries < cacheRecord.CachePolicy.RetriesCount) {
- ++cacheRecord.Retries;
- LOG_WARN_S(ctx, HttpLog, "IncomingRetry " << cacheRecord.GetName() << ": " << status << " " << error);
- SendCacheRequest(key, cacheRecord, ctx);
- return;
- }
- }
- }
- for (auto& waiter : cacheRecord.Waiters) {
- NHttp::THttpOutgoingResponsePtr response2;
- response2 = response->Duplicate(waiter->Get()->Request);
- ctx.Send(waiter->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response2));
- }
- cacheRecord.Waiters.clear();
- if (!error.empty()) {
- LOG_WARN_S(ctx, HttpLog, "Error from " << cacheRecord.GetName() << ": " << error);
- if (!cacheRecord.Response) {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingDiscard " << cacheRecord.GetName());
- DropCacheRecord(it);
- return;
- }
- }
- if (cacheRecord.CachePolicy.TimeToRefresh) {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingUpdate " << cacheRecord.GetName());
- cacheRecord.UpdateResponse(response, error, ctx.Now());
- if (!cacheRecord.Enqueued) {
- RefreshQueue.push({it->first, it->second.RefreshTime});
- cacheRecord.Enqueued = true;
- }
- LOG_DEBUG_S(ctx, HttpLog, "IncomingSchedule " << cacheRecord.GetName() << " at " << cacheRecord.RefreshTime << " until " << cacheRecord.DeathTime);
- } else {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingDrop " << cacheRecord.GetName());
- DropCacheRecord(it);
- }
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
- const NHttp::THttpIncomingRequest* request = event->Get()->Request.Get();
- TCachePolicy policy = GetCachePolicy(request);
- if (policy.TimeToExpire == TDuration() && policy.RetriesCount == 0) {
- TActorId handler = GetRequestHandler(event->Get()->Request);
- if (handler) {
- ctx.Send(event->Forward(handler));
- }
- return;
- }
- auto key = GetCacheKey(request, policy);
- auto it = Cache.find(key);
- if (it != Cache.end() && !policy.DiscardCache) {
- it->second.UpdateExpireTime();
- if (it->second.IsValid()) {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingRespond "
- << it->second.GetName()
- << " ("
- << ((it->second.Response != nullptr) ? ToString(it->second.Response->Size()) : TString("error"))
- << ")");
- NHttp::THttpOutgoingResponsePtr response = it->second.Response;
- if (response != nullptr) {
- response = response->Duplicate(event->Get()->Request);
- }
- ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- return;
- }
- } else {
- it = Cache.emplace(key, policy).first;
- it->second.CacheId = key.GetId(); // for debugging
- it->second.InitRequest(event->Get()->Request);
- if (policy.DiscardCache) {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingDiscardCache " << it->second.GetName());
- }
- LOG_DEBUG_S(ctx, HttpLog, "IncomingInitiate " << it->second.GetName());
- SendCacheRequest(key, it->second, ctx);
- }
- it->second.Waiters.emplace_back(std::move(event));
- }
-
- void HandleRefresh(const NActors::TActorContext& ctx) {
- while (!RefreshQueue.empty() && RefreshQueue.top().RefreshTime <= ctx.Now()) {
- TRefreshRecord rrec = RefreshQueue.top();
- RefreshQueue.pop();
- auto it = Cache.find(rrec.Key);
- if (it != Cache.end()) {
- it->second.Enqueued = false;
- if (it->second.DeathTime > ctx.Now()) {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingRefresh " << it->second.GetName());
- SendCacheRequest(it->first, it->second, ctx);
- } else {
- LOG_DEBUG_S(ctx, HttpLog, "IncomingForget " << it->second.GetName());
- DropCacheRecord(it);
- }
- }
- }
- ctx.Schedule(RefreshTimeout, new NActors::TEvents::TEvWakeup());
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingResponse, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingRequest, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvAddListeningPort, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvRegisterHandler, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
- HFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse, Handle);
- CFunc(NActors::TEvents::TSystem::Wakeup, HandleRefresh);
- }
- }
-};
-
-TCachePolicy GetDefaultCachePolicy(const THttpRequest* request, const TCachePolicy& defaultPolicy) {
- TCachePolicy policy = defaultPolicy;
- THeaders headers(request->Headers);
- TStringBuf cacheControl(headers["Cache-Control"]);
- while (TStringBuf cacheItem = cacheControl.NextTok(',')) {
- Trim(cacheItem, ' ');
- if (cacheItem == "no-store" || cacheItem == "no-cache") {
- policy.DiscardCache = true;
- }
- TStringBuf itemName = cacheItem.NextTok('=');
- TrimEnd(itemName, ' ');
- TrimBegin(cacheItem, ' ');
- if (itemName == "max-age") {
- policy.TimeToRefresh = policy.TimeToExpire = TDuration::Seconds(FromString(cacheItem));
- }
- if (itemName == "min-fresh") {
- policy.TimeToRefresh = policy.TimeToExpire = TDuration::Seconds(FromString(cacheItem));
- }
- if (itemName == "stale-if-error") {
- policy.KeepOnError = true;
- }
- }
- return policy;
-}
-
-NActors::IActor* CreateHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy) {
- return new THttpOutgoingCacheActor(httpProxyId, std::move(cachePolicy));
-}
-
-NActors::IActor* CreateOutgoingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy) {
- return new THttpOutgoingCacheActor(httpProxyId, std::move(cachePolicy));
-}
-
-NActors::IActor* CreateIncomingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy) {
- return new THttpIncomingCacheActor(httpProxyId, std::move(cachePolicy));
-}
-
-}
diff --git a/library/cpp/actors/http/http_cache.h b/library/cpp/actors/http/http_cache.h
deleted file mode 100644
index ac38bdcac8..0000000000
--- a/library/cpp/actors/http/http_cache.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-#include <library/cpp/actors/core/actor.h>
-#include "http.h"
-
-namespace NHttp {
-
-struct TCachePolicy {
- TDuration TimeToExpire;
- TDuration TimeToRefresh;
- TDuration PaceToRefresh;
- bool KeepOnError = false;
- bool DiscardCache = false;
- TArrayRef<TString> HeadersToCacheKey;
- TArrayRef<TString> StatusesToRetry;
- ui32 RetriesCount = 0;
-
- TCachePolicy() = default;
-};
-
-using TGetCachePolicy = std::function<TCachePolicy(const THttpRequest*)>;
-
-NActors::IActor* CreateHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy);
-NActors::IActor* CreateOutgoingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy);
-NActors::IActor* CreateIncomingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy);
-TCachePolicy GetDefaultCachePolicy(const THttpRequest* request, const TCachePolicy& policy = TCachePolicy());
-
-}
diff --git a/library/cpp/actors/http/http_compress.cpp b/library/cpp/actors/http/http_compress.cpp
deleted file mode 100644
index b6593fe99d..0000000000
--- a/library/cpp/actors/http/http_compress.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "http.h"
-
-#include <zlib.h>
-
-namespace NHttp {
-
-TString CompressDeflate(TStringBuf source) {
- int compressionlevel = Z_BEST_COMPRESSION;
- z_stream zs = {};
-
- if (deflateInit(&zs, compressionlevel) != Z_OK) {
- throw yexception() << "deflateInit failed while compressing";
- }
-
- zs.next_in = (Bytef*)source.data();
- zs.avail_in = source.size();
-
- int ret;
- char outbuffer[32768];
- TString result;
-
- // retrieve the compressed bytes blockwise
- do {
- zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
- zs.avail_out = sizeof(outbuffer);
-
- ret = deflate(&zs, Z_FINISH);
-
- if (result.size() < zs.total_out) {
- result.append(outbuffer, zs.total_out - result.size());
- }
- } while (ret == Z_OK);
-
- deflateEnd(&zs);
-
- if (ret != Z_STREAM_END) {
- throw yexception() << "Exception during zlib compression: (" << ret << ") " << zs.msg;
- }
- return result;
-}
-
-TString DecompressDeflate(TStringBuf source) {
- z_stream zs = {};
-
- if (inflateInit(&zs) != Z_OK) {
- throw yexception() << "inflateInit failed while decompressing";
- }
-
- zs.next_in = (Bytef*)source.data();
- zs.avail_in = source.size();
-
- int ret;
- char outbuffer[32768];
- TString result;
-
- // retrieve the decompressed bytes blockwise
- do {
- zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
- zs.avail_out = sizeof(outbuffer);
-
- ret = inflate(&zs, Z_NO_FLUSH);
-
- if (result.size() < zs.total_out) {
- result.append(outbuffer, zs.total_out - result.size());
- }
- } while (ret == Z_OK);
-
- inflateEnd(&zs);
-
- if (ret != Z_STREAM_END) {
- throw yexception() << "Exception during zlib decompression: (" << ret << ") " << zs.msg;
- }
- return result;
-}
-
-}
diff --git a/library/cpp/actors/http/http_config.h b/library/cpp/actors/http/http_config.h
deleted file mode 100644
index 1a2f8646a3..0000000000
--- a/library/cpp/actors/http/http_config.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-#include <util/network/sock.h>
-#include <library/cpp/actors/core/log.h>
-#include <library/cpp/actors/protos/services_common.pb.h>
-
-class TInet64StreamSocket;
-
-namespace NHttp {
-
-struct THttpConfig {
- static constexpr NActors::NLog::EComponent HttpLog = NActorsServices::EServiceCommon::HTTP;
- static constexpr size_t BUFFER_SIZE = 64 * 1024;
- static constexpr size_t BUFFER_MIN_STEP = 10 * 1024;
- static constexpr int LISTEN_QUEUE = 10;
- static constexpr TDuration SOCKET_TIMEOUT = TDuration::MilliSeconds(60000);
- static constexpr TDuration CONNECTION_TIMEOUT = TDuration::MilliSeconds(60000);
- using SocketType = TInet64StreamSocket;
- using SocketAddressType = std::shared_ptr<ISockAddr>;
-};
-
-}
diff --git a/library/cpp/actors/http/http_proxy.cpp b/library/cpp/actors/http/http_proxy.cpp
deleted file mode 100644
index 74bf497632..0000000000
--- a/library/cpp/actors/http/http_proxy.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/monlib/metrics/metric_registry.h>
-#include "http_proxy.h"
-
-namespace NHttp {
-
-class THttpProxy : public NActors::TActorBootstrapped<THttpProxy>, public THttpConfig {
-public:
- IActor* AddListeningPort(TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
- IActor* listeningSocket = CreateHttpAcceptorActor(ctx.SelfID, Poller);
- TActorId acceptorId = ctx.Register(listeningSocket);
- ctx.Send(event->Forward(acceptorId));
- Acceptors.emplace_back(acceptorId);
- return listeningSocket;
- }
-
- IActor* AddOutgoingConnection(bool secure, const NActors::TActorContext& ctx) {
- IActor* connectionSocket = CreateOutgoingConnectionActor(ctx.SelfID, secure, Poller);
- TActorId connectionId = ctx.Register(connectionSocket);
- Connections.emplace(connectionId);
- return connectionSocket;
- }
-
- void Bootstrap(const NActors::TActorContext& ctx) {
- Poller = ctx.Register(NActors::CreatePollerActor());
- Become(&THttpProxy::StateWork);
- }
-
- THttpProxy(std::weak_ptr<NMonitoring::TMetricRegistry> registry)
- : Registry(std::move(registry))
- {}
-
- static constexpr char ActorName[] = "HTTP_PROXY_ACTOR";
-
-protected:
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHttpProxy::TEvAddListeningPort, Handle);
- HFunc(TEvHttpProxy::TEvRegisterHandler, Handle);
- HFunc(TEvHttpProxy::TEvHttpIncomingRequest, Handle);
- HFunc(TEvHttpProxy::TEvHttpOutgoingRequest, Handle);
- HFunc(TEvHttpProxy::TEvHttpIncomingResponse, Handle);
- HFunc(TEvHttpProxy::TEvHttpOutgoingResponse, Handle);
- HFunc(TEvHttpProxy::TEvHttpAcceptorClosed, Handle);
- HFunc(TEvHttpProxy::TEvHttpConnectionClosed, Handle);
- HFunc(TEvHttpProxy::TEvResolveHostRequest, Handle);
- HFunc(TEvHttpProxy::TEvReportSensors, Handle);
- HFunc(NActors::TEvents::TEvPoison, Handle);
- }
- }
-
- void PassAway() override {
- Send(Poller, new NActors::TEvents::TEvPoisonPill());
- for (const NActors::TActorId& connection : Connections) {
- Send(connection, new NActors::TEvents::TEvPoisonPill());
- }
- for (const NActors::TActorId& acceptor : Acceptors) {
- Send(acceptor, new NActors::TEvents::TEvPoisonPill());
- }
- NActors::TActorBootstrapped<THttpProxy>::PassAway();
- }
-
- void Handle(TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
- TStringBuf url = event->Get()->Request->URL.Before('?');
- THashMap<TString, TActorId>::iterator it;
- while (!url.empty()) {
- it = Handlers.find(url);
- if (it != Handlers.end()) {
- ctx.Send(event->Forward(it->second));
- return;
- } else {
- if (url.EndsWith('/')) {
- url.Chop(1);
- } else {
- size_t pos = url.rfind('/');
- if (pos == TStringBuf::npos) {
- break;
- } else {
- url = url.substr(0, pos + 1);
- }
- }
- }
- }
- ctx.Send(event->Sender, new TEvHttpProxy::TEvHttpOutgoingResponse(event->Get()->Request->CreateResponseNotFound()));
- }
-
- void Handle(TEvHttpProxy::TEvHttpIncomingResponse::TPtr event, const NActors::TActorContext& ctx) {
- Y_UNUSED(event);
- Y_UNUSED(ctx);
- Y_ABORT("This event shouldn't be there, it should go to the http connection owner directly");
- }
-
- void Handle(TEvHttpProxy::TEvHttpOutgoingResponse::TPtr event, const NActors::TActorContext& ctx) {
- Y_UNUSED(event);
- Y_UNUSED(ctx);
- Y_ABORT("This event shouldn't be there, it should go to the http connection directly");
- }
-
- void Handle(TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
- bool secure(event->Get()->Request->Secure);
- NActors::IActor* actor = AddOutgoingConnection(secure, ctx);
- ctx.Send(event->Forward(actor->SelfId()));
- }
-
- void Handle(TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
- AddListeningPort(event, ctx);
- }
-
- void Handle(TEvHttpProxy::TEvHttpAcceptorClosed::TPtr event, const NActors::TActorContext&) {
- for (auto it = Acceptors.begin(); it != Acceptors.end(); ++it) {
- if (*it == event->Get()->ConnectionID) {
- Acceptors.erase(it);
- break;
- }
- }
- }
-
- void Handle(TEvHttpProxy::TEvHttpConnectionClosed::TPtr event, const NActors::TActorContext&) {
- Connections.erase(event->Get()->ConnectionID);
- }
-
- void Handle(TEvHttpProxy::TEvRegisterHandler::TPtr event, const NActors::TActorContext& ctx) {
- LOG_TRACE_S(ctx, HttpLog, "Register handler " << event->Get()->Path << " to " << event->Get()->Handler);
- Handlers[event->Get()->Path] = event->Get()->Handler;
- }
-
- void Handle(TEvHttpProxy::TEvResolveHostRequest::TPtr event, const NActors::TActorContext& ctx) {
- const TString& host(event->Get()->Host);
- auto it = Hosts.find(host);
- if (it == Hosts.end() || it->second.DeadlineTime > ctx.Now()) {
- TString addressPart;
- TIpPort portPart = 0;
- CrackAddress(host, addressPart, portPart);
- if (IsIPv6(addressPart)) {
- if (it == Hosts.end()) {
- it = Hosts.emplace(host, THostEntry()).first;
- }
- it->second.Address = std::make_shared<TSockAddrInet6>(addressPart.data(), portPart);
- it->second.DeadlineTime = ctx.Now() + HostsTimeToLive;
- } else if (IsIPv4(addressPart)) {
- if (it == Hosts.end()) {
- it = Hosts.emplace(host, THostEntry()).first;
- }
- it->second.Address = std::make_shared<TSockAddrInet>(addressPart.data(), portPart);
- it->second.DeadlineTime = ctx.Now() + HostsTimeToLive;
- } else {
- // TODO(xenoxeno): move to another, possible blocking actor
- try {
- const NDns::TResolvedHost* result = NDns::CachedResolve(NDns::TResolveInfo(addressPart, portPart));
- if (result != nullptr) {
- auto pAddr = result->Addr.Begin();
- while (pAddr != result->Addr.End() && pAddr->ai_family != AF_INET && pAddr->ai_family != AF_INET6) {
- ++pAddr;
- }
- if (pAddr == result->Addr.End()) {
- ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse("Invalid address family resolved"));
- return;
- }
- THttpConfig::SocketAddressType address;
- switch (pAddr->ai_family) {
- case AF_INET:
- address = std::make_shared<TSockAddrInet>();
- break;
- case AF_INET6:
- address = std::make_shared<TSockAddrInet6>();
- break;
- }
- if (address) {
- memcpy(address->SockAddr(), pAddr->ai_addr, pAddr->ai_addrlen);
- LOG_DEBUG_S(ctx, HttpLog, "Host " << host << " resolved to " << address->ToString());
- if (it == Hosts.end()) {
- it = Hosts.emplace(host, THostEntry()).first;
- }
- it->second.Address = address;
- it->second.DeadlineTime = ctx.Now() + HostsTimeToLive;
- }
- } else {
- ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse("Error resolving host"));
- return;
- }
- }
- catch (const yexception& e) {
- ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse(e.what()));
- return;
- }
- }
- }
- ctx.Send(event->Sender, new TEvHttpProxy::TEvResolveHostResponse(it->first, it->second.Address));
- }
-
- void Handle(TEvHttpProxy::TEvReportSensors::TPtr event, const NActors::TActorContext&) {
- const TEvHttpProxy::TEvReportSensors& sensors(*event->Get());
- const static TString urlNotFound = "not-found";
- const TString& url = (sensors.Status == "404" ? urlNotFound : sensors.Url);
-
- std::shared_ptr<NMonitoring::TMetricRegistry> registry = Registry.lock();
- if (registry) {
- registry->Rate(
- {
- {"sensor", "count"},
- {"direction", sensors.Direction},
- {"peer", sensors.Host},
- {"url", url},
- {"status", sensors.Status}
- })->Inc();
- registry->HistogramRate(
- {
- {"sensor", "time_us"},
- {"direction", sensors.Direction},
- {"peer", sensors.Host},
- {"url", url},
- {"status", sensors.Status}
- },
- NMonitoring::ExplicitHistogram({1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 30000, 60000}))->Record(sensors.Time.MicroSeconds());
- registry->HistogramRate(
- {
- {"sensor", "time_ms"},
- {"direction", sensors.Direction},
- {"peer", sensors.Host},
- {"url", url},
- {"status", sensors.Status}
- },
- NMonitoring::ExplicitHistogram({1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 30000, 60000}))->Record(sensors.Time.MilliSeconds());
- }
- }
-
- void Handle(NActors::TEvents::TEvPoison::TPtr, const NActors::TActorContext&) {
- for (const TActorId& acceptor : Acceptors) {
- Send(acceptor, new NActors::TEvents::TEvPoisonPill());
- }
- for (const TActorId& connection : Connections) {
- Send(connection, new NActors::TEvents::TEvPoisonPill());
- }
- PassAway();
- }
-
- NActors::TActorId Poller;
- TVector<TActorId> Acceptors;
-
- struct THostEntry {
- THttpConfig::SocketAddressType Address;
- TInstant DeadlineTime;
- };
-
- static constexpr TDuration HostsTimeToLive = TDuration::Seconds(60);
-
- THashMap<TString, THostEntry> Hosts;
- THashMap<TString, TActorId> Handlers;
- THashSet<TActorId> Connections; // outgoing
- std::weak_ptr<NMonitoring::TMetricRegistry> Registry;
-};
-
-TEvHttpProxy::TEvReportSensors* BuildOutgoingRequestSensors(const THttpOutgoingRequestPtr& request, const THttpIncomingResponsePtr& response) {
- return new TEvHttpProxy::TEvReportSensors(
- "out",
- request->Host,
- request->URL.Before('?'),
- response ? response->Status : "504",
- TDuration::Seconds(std::abs(request->Timer.Passed()))
- );
-}
-
-TEvHttpProxy::TEvReportSensors* BuildIncomingRequestSensors(const THttpIncomingRequestPtr& request, const THttpOutgoingResponsePtr& response) {
- const auto& sensors = response->Sensors;
- if (sensors) {
- return new TEvHttpProxy::TEvReportSensors(*sensors);
- }
- return new TEvHttpProxy::TEvReportSensors(
- "in",
- request->Host,
- request->URL.Before('?'),
- response->Status,
- TDuration::Seconds(std::abs(request->Timer.Passed()))
- );
-}
-
-NActors::IActor* CreateHttpProxy(std::weak_ptr<NMonitoring::TMetricRegistry> registry) {
- return new THttpProxy(std::move(registry));
-}
-
-bool IsIPv6(const TString& host) {
- if (host.find_first_not_of(":0123456789abcdef") != TString::npos) {
- return false;
- }
- if (std::count(host.begin(), host.end(), ':') < 2) {
- return false;
- }
- return true;
-}
-
-bool IsIPv4(const TString& host) {
- if (host.find_first_not_of(".0123456789") != TString::npos) {
- return false;
- }
- if (std::count(host.begin(), host.end(), '.') != 3) {
- return false;
- }
- return true;
-}
-
-bool CrackURL(TStringBuf url, TStringBuf& scheme, TStringBuf& host, TStringBuf& uri) {
- url.TrySplit("://", scheme, url);
- auto pos = url.find('/');
- if (pos == TStringBuf::npos) {
- host = url;
- } else {
- host = url.substr(0, pos);
- uri = url.substr(pos);
- }
- return true;
-}
-
-void CrackAddress(const TString& address, TString& hostname, TIpPort& port) {
- size_t first_colon_pos = address.find(':');
- if (first_colon_pos != TString::npos) {
- size_t last_colon_pos = address.rfind(':');
- if (last_colon_pos == first_colon_pos) {
- // only one colon, simple case
- port = FromStringWithDefault<TIpPort>(address.substr(first_colon_pos + 1), 0);
- hostname = address.substr(0, first_colon_pos);
- } else {
- // ipv6?
- size_t closing_bracket_pos = address.rfind(']');
- if (closing_bracket_pos == TString::npos || closing_bracket_pos > last_colon_pos) {
- // whole address is ipv6 host
- hostname = address;
- } else {
- port = FromStringWithDefault<TIpPort>(address.substr(last_colon_pos + 1), 0);
- hostname = address.substr(0, last_colon_pos);
- }
- if (hostname.StartsWith('[') && hostname.EndsWith(']')) {
- hostname = hostname.substr(1, hostname.size() - 2);
- }
- }
- } else {
- hostname = address;
- }
-}
-
-
-void TrimBegin(TStringBuf& target, char delim) {
- while (!target.empty() && *target.begin() == delim) {
- target.Skip(1);
- }
-}
-
-void TrimEnd(TStringBuf& target, char delim) {
- while (!target.empty() && target.back() == delim) {
- target.Trunc(target.size() - 1);
- }
-}
-
-void Trim(TStringBuf& target, char delim) {
- TrimBegin(target, delim);
- TrimEnd(target, delim);
-}
-
-void TrimEnd(TString& target, char delim) {
- while (!target.empty() && target.back() == delim) {
- target.resize(target.size() - 1);
- }
-}
-
-}
diff --git a/library/cpp/actors/http/http_proxy.h b/library/cpp/actors/http/http_proxy.h
deleted file mode 100644
index d9a2c6a71c..0000000000
--- a/library/cpp/actors/http/http_proxy.h
+++ /dev/null
@@ -1,246 +0,0 @@
-#pragma once
-#include <library/cpp/actors/core/actorsystem.h>
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/actors/core/event_local.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/log.h>
-#include <library/cpp/actors/interconnect/poller_actor.h>
-#include <library/cpp/dns/cache.h>
-#include <library/cpp/monlib/metrics/metric_registry.h>
-#include <util/generic/variant.h>
-#include "http.h"
-#include "http_proxy_sock64.h"
-#include "http_proxy_ssl.h"
-
-namespace NHttp {
-
-struct TSocketDescriptor : NActors::TSharedDescriptor, THttpConfig {
- SocketType Socket;
-
- TSocketDescriptor() = default;
-
- TSocketDescriptor(int af)
- : Socket(af)
- {
- }
-
- TSocketDescriptor(SocketType&& s)
- : Socket(std::move(s))
- {}
-
- int GetDescriptor() override {
- return static_cast<SOCKET>(Socket);
- }
-};
-
-struct TEvHttpProxy {
- enum EEv {
- EvAddListeningPort = EventSpaceBegin(NActors::TEvents::ES_HTTP),
- EvConfirmListen,
- EvRegisterHandler,
- EvHttpIncomingRequest,
- EvHttpOutgoingRequest,
- EvHttpIncomingResponse,
- EvHttpOutgoingResponse,
- EvHttpConnectionOpened,
- EvHttpConnectionClosed,
- EvHttpAcceptorClosed,
- EvResolveHostRequest,
- EvResolveHostResponse,
- EvReportSensors,
- EvEnd
- };
-
- static_assert(EvEnd < EventSpaceEnd(NActors::TEvents::ES_HTTP), "ES_HTTP event space is too small.");
-
- struct TEvAddListeningPort : NActors::TEventLocal<TEvAddListeningPort, EvAddListeningPort> {
- TString Address;
- TIpPort Port;
- TString WorkerName;
- bool Secure = false;
- TString CertificateFile;
- TString PrivateKeyFile;
- TString SslCertificatePem;
- std::vector<TString> CompressContentTypes;
-
- TEvAddListeningPort() = default;
-
- TEvAddListeningPort(TIpPort port)
- : Port(port)
- {}
-
- TEvAddListeningPort(TIpPort port, const TString& workerName)
- : Port(port)
- , WorkerName(workerName)
- {}
- };
-
- struct TEvConfirmListen : NActors::TEventLocal<TEvConfirmListen, EvConfirmListen> {
- THttpConfig::SocketAddressType Address;
- std::shared_ptr<THttpEndpointInfo> Endpoint;
-
- TEvConfirmListen(const THttpConfig::SocketAddressType& address, std::shared_ptr<THttpEndpointInfo> endpoint)
- : Address(address)
- , Endpoint(std::move(endpoint))
- {}
- };
-
- struct TEvRegisterHandler : NActors::TEventLocal<TEvRegisterHandler, EvRegisterHandler> {
- TString Path;
- TActorId Handler;
-
- TEvRegisterHandler(const TString& path, const TActorId& handler)
- : Path(path)
- , Handler(handler)
- {}
- };
-
- struct TEvHttpIncomingRequest : NActors::TEventLocal<TEvHttpIncomingRequest, EvHttpIncomingRequest> {
- THttpIncomingRequestPtr Request;
-
- TEvHttpIncomingRequest(THttpIncomingRequestPtr request)
- : Request(std::move(request))
- {}
- };
-
- struct TEvHttpOutgoingRequest : NActors::TEventLocal<TEvHttpOutgoingRequest, EvHttpOutgoingRequest> {
- THttpOutgoingRequestPtr Request;
- TDuration Timeout;
-
- TEvHttpOutgoingRequest(THttpOutgoingRequestPtr request)
- : Request(std::move(request))
- {}
-
- TEvHttpOutgoingRequest(THttpOutgoingRequestPtr request, TDuration timeout)
- : Request(std::move(request))
- , Timeout(timeout)
- {}
- };
-
- struct TEvHttpIncomingResponse : NActors::TEventLocal<TEvHttpIncomingResponse, EvHttpIncomingResponse> {
- THttpOutgoingRequestPtr Request;
- THttpIncomingResponsePtr Response;
- TString Error;
-
- TEvHttpIncomingResponse(THttpOutgoingRequestPtr request, THttpIncomingResponsePtr response, const TString& error)
- : Request(std::move(request))
- , Response(std::move(response))
- , Error(error)
- {}
-
- TEvHttpIncomingResponse(THttpOutgoingRequestPtr request, THttpIncomingResponsePtr response)
- : Request(std::move(request))
- , Response(std::move(response))
- {}
-
- TString GetError() const {
- TStringBuilder error;
- if (Response != nullptr && !Response->Status.StartsWith('2')) {
- error << Response->Status << ' ' << Response->Message;
- }
- if (!Error.empty()) {
- if (!error.empty()) {
- error << ';';
- }
- error << Error;
- }
- return error;
- }
- };
-
- struct TEvHttpOutgoingResponse : NActors::TEventLocal<TEvHttpOutgoingResponse, EvHttpOutgoingResponse> {
- THttpOutgoingResponsePtr Response;
-
- TEvHttpOutgoingResponse(THttpOutgoingResponsePtr response)
- : Response(std::move(response))
- {}
- };
-
- struct TEvHttpConnectionOpened : NActors::TEventLocal<TEvHttpConnectionOpened, EvHttpConnectionOpened> {
- TString PeerAddress;
- TActorId ConnectionID;
-
- TEvHttpConnectionOpened(const TString& peerAddress, const TActorId& connectionID)
- : PeerAddress(peerAddress)
- , ConnectionID(connectionID)
- {}
- };
-
- struct TEvHttpConnectionClosed : NActors::TEventLocal<TEvHttpConnectionClosed, EvHttpConnectionClosed> {
- TActorId ConnectionID;
- TDeque<THttpIncomingRequestPtr> RecycledRequests;
-
- TEvHttpConnectionClosed(const TActorId& connectionID)
- : ConnectionID(connectionID)
- {}
-
- TEvHttpConnectionClosed(const TActorId& connectionID, TDeque<THttpIncomingRequestPtr> recycledRequests)
- : ConnectionID(connectionID)
- , RecycledRequests(std::move(recycledRequests))
- {}
- };
-
- struct TEvHttpAcceptorClosed : NActors::TEventLocal<TEvHttpAcceptorClosed, EvHttpAcceptorClosed> {
- TActorId ConnectionID;
-
- TEvHttpAcceptorClosed(const TActorId& connectionID)
- : ConnectionID(connectionID)
- {}
- };
-
- struct TEvResolveHostRequest : NActors::TEventLocal<TEvResolveHostRequest, EvResolveHostRequest> {
- TString Host;
-
- TEvResolveHostRequest(const TString& host)
- : Host(host)
- {}
- };
-
- struct TEvResolveHostResponse : NActors::TEventLocal<TEvResolveHostResponse, EvResolveHostResponse> {
- TString Host;
- THttpConfig::SocketAddressType Address;
- TString Error;
-
- TEvResolveHostResponse(const TString& host, THttpConfig::SocketAddressType address)
- : Host(host)
- , Address(address)
- {}
-
- TEvResolveHostResponse(const TString& error)
- : Error(error)
- {}
- };
-
- struct TEvReportSensors : TSensors, NActors::TEventLocal<TEvReportSensors, EvReportSensors> {
- using TSensors::TSensors;
-
- TEvReportSensors(const TSensors& sensors)
- : TSensors(sensors)
- {}
- };
-};
-
-struct TPrivateEndpointInfo : THttpEndpointInfo {
- TActorId Proxy;
- TActorId Owner;
- TSslHelpers::TSslHolder<SSL_CTX> SecureContext;
-
- TPrivateEndpointInfo(const std::vector<TString>& compressContentTypes)
- : THttpEndpointInfo(compressContentTypes)
- {}
-};
-
-NActors::IActor* CreateHttpProxy(std::weak_ptr<NMonitoring::TMetricRegistry> registry = NMonitoring::TMetricRegistry::SharedInstance());
-NActors::IActor* CreateHttpAcceptorActor(const TActorId& owner, const TActorId& poller);
-NActors::IActor* CreateOutgoingConnectionActor(const TActorId& owner, bool secure, const TActorId& poller);
-NActors::IActor* CreateIncomingConnectionActor(
- std::shared_ptr<TPrivateEndpointInfo> endpoint,
- TIntrusivePtr<TSocketDescriptor> socket,
- THttpConfig::SocketAddressType address,
- THttpIncomingRequestPtr recycledRequest = nullptr);
-TEvHttpProxy::TEvReportSensors* BuildOutgoingRequestSensors(const THttpOutgoingRequestPtr& request, const THttpIncomingResponsePtr& response);
-TEvHttpProxy::TEvReportSensors* BuildIncomingRequestSensors(const THttpIncomingRequestPtr& request, const THttpOutgoingResponsePtr& response);
-
-}
diff --git a/library/cpp/actors/http/http_proxy_acceptor.cpp b/library/cpp/actors/http/http_proxy_acceptor.cpp
deleted file mode 100644
index c007f747eb..0000000000
--- a/library/cpp/actors/http/http_proxy_acceptor.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-#include <util/network/sock.h>
-#include "http_proxy.h"
-#include "http_proxy_ssl.h"
-
-namespace NHttp {
-
-class TAcceptorActor : public NActors::TActor<TAcceptorActor>, public THttpConfig {
-public:
- using TBase = NActors::TActor<TAcceptorActor>;
- const TActorId Owner;
- const TActorId Poller;
- TIntrusivePtr<TSocketDescriptor> Socket;
- NActors::TPollerToken::TPtr PollerToken;
- THashSet<TActorId> Connections;
- TDeque<THttpIncomingRequestPtr> RecycledRequests;
- std::shared_ptr<TPrivateEndpointInfo> Endpoint;
-
- TAcceptorActor(const TActorId& owner, const TActorId& poller)
- : NActors::TActor<TAcceptorActor>(&TAcceptorActor::StateInit)
- , Owner(owner)
- , Poller(poller)
- {
- }
-
- static constexpr char ActorName[] = "HTTP_ACCEPTOR_ACTOR";
-
-protected:
- STFUNC(StateListening) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NActors::TEvPollerRegisterResult, Handle);
- HFunc(NActors::TEvPollerReady, Handle);
- HFunc(TEvHttpProxy::TEvHttpConnectionClosed, Handle);
- HFunc(TEvHttpProxy::TEvReportSensors, Handle);
- }
- }
-
- STFUNC(StateInit) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHttpProxy::TEvAddListeningPort, HandleInit);
- }
- }
-
- void HandleInit(TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) {
- TString address = event->Get()->Address;
- ui16 port = event->Get()->Port;
- Socket = new TSocketDescriptor(SocketType::GuessAddressFamily(address));
- // for unit tests :(
- SetSockOpt(Socket->Socket, SOL_SOCKET, SO_REUSEADDR, (int)true);
-#ifdef SO_REUSEPORT
- SetSockOpt(Socket->Socket, SOL_SOCKET, SO_REUSEPORT, (int)true);
-#endif
- SocketAddressType bindAddress(Socket->Socket.MakeAddress(address, port));
- Endpoint = std::make_shared<TPrivateEndpointInfo>(event->Get()->CompressContentTypes);
- Endpoint->Owner = ctx.SelfID;
- Endpoint->Proxy = Owner;
- Endpoint->WorkerName = event->Get()->WorkerName;
- Endpoint->Secure = event->Get()->Secure;
- int err = 0;
- if (Endpoint->Secure) {
- if (!event->Get()->SslCertificatePem.empty()) {
- Endpoint->SecureContext = TSslHelpers::CreateServerContext(event->Get()->SslCertificatePem);
- } else {
- Endpoint->SecureContext = TSslHelpers::CreateServerContext(event->Get()->CertificateFile, event->Get()->PrivateKeyFile);
- }
- if (Endpoint->SecureContext == nullptr) {
- err = -1;
- LOG_WARN_S(ctx, HttpLog, "Failed to construct server security context");
- }
- }
- if (err == 0) {
- err = Socket->Socket.Bind(bindAddress.get());
- if (err != 0) {
- LOG_WARN_S(
- ctx,
- HttpLog,
- "Failed to bind " << bindAddress->ToString()
- << ", code: " << err);
- }
- }
- TStringBuf schema = Endpoint->Secure ? "https://" : "http://";
- if (err == 0) {
- err = Socket->Socket.Listen(LISTEN_QUEUE);
- if (err == 0) {
- LOG_INFO_S(ctx, HttpLog, "Listening on " << schema << bindAddress->ToString());
- SetNonBlock(Socket->Socket);
- ctx.Send(Poller, new NActors::TEvPollerRegister(Socket, SelfId(), SelfId()));
- TBase::Become(&TAcceptorActor::StateListening);
- ctx.Send(event->Sender, new TEvHttpProxy::TEvConfirmListen(bindAddress, Endpoint), 0, event->Cookie);
- return;
- } else {
- LOG_WARN_S(
- ctx,
- HttpLog,
- "Failed to listen on " << schema << bindAddress->ToString()
- << ", code: " << err);
- }
- }
- LOG_WARN_S(ctx, HttpLog, "Failed to init - retrying...");
- ctx.ExecutorThread.Schedule(TDuration::Seconds(1), event.Release());
- }
-
- void Die(const NActors::TActorContext& ctx) override {
- ctx.Send(Owner, new TEvHttpProxy::TEvHttpAcceptorClosed(ctx.SelfID));
- for (const NActors::TActorId& connection : Connections) {
- ctx.Send(connection, new NActors::TEvents::TEvPoisonPill());
- }
- }
-
- 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) {
- for (;;) {
- SocketAddressType addr;
- std::optional<SocketType> s = Socket->Socket.Accept(addr);
- if (!s) {
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
- Y_ABORT_UNLESS(PollerToken);
- if (PollerToken->RequestReadNotificationAfterWouldBlock()) {
- continue; // we can try it again
- }
- }
- break;
- }
- TIntrusivePtr<TSocketDescriptor> socket = new TSocketDescriptor(std::move(s).value());
- NActors::IActor* connectionSocket = nullptr;
- if (RecycledRequests.empty()) {
- connectionSocket = CreateIncomingConnectionActor(Endpoint, socket, addr);
- } else {
- connectionSocket = CreateIncomingConnectionActor(Endpoint, socket, addr, std::move(RecycledRequests.front()));
- RecycledRequests.pop_front();
- }
- NActors::TActorId connectionId = ctx.Register(connectionSocket);
- ctx.Send(Poller, new NActors::TEvPollerRegister(socket, connectionId, connectionId));
- Connections.emplace(connectionId);
- }
- }
-
- void Handle(TEvHttpProxy::TEvHttpConnectionClosed::TPtr event, const NActors::TActorContext&) {
- Connections.erase(event->Get()->ConnectionID);
- for (auto& req : event->Get()->RecycledRequests) {
- req->Clear();
- RecycledRequests.push_back(std::move(req));
- }
- }
-
- void Handle(TEvHttpProxy::TEvReportSensors::TPtr event, const NActors::TActorContext& ctx) {
- ctx.Send(event->Forward(Owner));
- }
-};
-
-NActors::IActor* CreateHttpAcceptorActor(const TActorId& owner, const TActorId& poller) {
- return new TAcceptorActor(owner, poller);
-}
-
-}
diff --git a/library/cpp/actors/http/http_proxy_incoming.cpp b/library/cpp/actors/http/http_proxy_incoming.cpp
deleted file mode 100644
index b98b3c09f3..0000000000
--- a/library/cpp/actors/http/http_proxy_incoming.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-#include "http_proxy.h"
-#include "http_proxy_sock_impl.h"
-
-namespace NHttp {
-
-using namespace NActors;
-
-template <typename TSocketImpl>
-class TIncomingConnectionActor : public TActor<TIncomingConnectionActor<TSocketImpl>>, public TSocketImpl, virtual public THttpConfig {
-public:
- using TBase = TActor<TIncomingConnectionActor<TSocketImpl>>;
- static constexpr bool RecycleRequests = true;
-
- std::shared_ptr<TPrivateEndpointInfo> Endpoint;
- SocketAddressType Address;
- TList<THttpIncomingRequestPtr> Requests;
- THashMap<THttpIncomingRequestPtr, THttpOutgoingResponsePtr> Responses;
- THttpIncomingRequestPtr CurrentRequest;
- THttpOutgoingResponsePtr CurrentResponse;
- TDeque<THttpIncomingRequestPtr> RecycledRequests;
-
- THPTimer InactivityTimer;
- static constexpr TDuration InactivityTimeout = TDuration::Minutes(2);
- TEvPollerReady* InactivityEvent = nullptr;
-
- TPollerToken::TPtr PollerToken;
-
- TIncomingConnectionActor(
- std::shared_ptr<TPrivateEndpointInfo> endpoint,
- TIntrusivePtr<TSocketDescriptor> socket,
- SocketAddressType address,
- THttpIncomingRequestPtr recycledRequest = nullptr)
- : TBase(&TIncomingConnectionActor::StateAccepting)
- , TSocketImpl(std::move(socket))
- , Endpoint(std::move(endpoint))
- , Address(address)
- {
- if (recycledRequest != nullptr) {
- RecycledRequests.emplace_back(std::move(recycledRequest));
- }
- TSocketImpl::SetNonBlock();
- }
-
- static constexpr char ActorName[] = "IN_CONNECTION_ACTOR";
-
- void CleanupRequest(THttpIncomingRequestPtr& request) {
- if (RecycleRequests) {
- request->Clear();
- RecycledRequests.push_back(std::move(request));
- } else {
- request = nullptr;
- }
- }
-
- void CleanupResponse(THttpOutgoingResponsePtr& response) {
- CleanupRequest(response->Request);
- // TODO: maybe recycle too?
- response = nullptr;
- }
-
- TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parent) override {
- 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();
- TBase::Die(ctx);
- }
-
-protected:
- 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;
- for (;;) {
- if ((res = TSocketImpl::OnAccept(Endpoint, read, write)) != 1) {
- if (-res == EAGAIN) {
- if (PollerToken && PollerToken->RequestReadNotificationAfterWouldBlock()) {
- continue;
- }
- return; // wait for further notifications
- } else {
- LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in Accept: " << strerror(-res));
- return Die(ctx);
- }
- }
- break;
- }
- TBase::Become(&TIncomingConnectionActor::StateConnected);
- ctx.Send(ctx.SelfID, new TEvPollerReady(nullptr, true, true));
- }
-
- 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) {
- 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();
- CurrentRequest->Address = Address;
- CurrentRequest->Endpoint = Endpoint;
- } else {
- CurrentRequest = new THttpIncomingRequest(Endpoint, Address);
- }
- }
- 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;
- }
- if (PollerToken->RequestNotificationAfterWouldBlock(read, write)) {
- continue;
- }
- }
- break;
- } else if (-res == EINTR) {
- continue;
- } else if (!res) {
- // connection closed
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed");
- return Die(ctx);
- } 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);
- }
- }
-
- 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) {
- Respond(event->Get()->Response, ctx);
- }
-
- bool Respond(THttpOutgoingResponsePtr response, const TActorContext& ctx) {
- THttpIncomingRequestPtr request = response->GetRequest();
- response->Finish();
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") <- (" << response->Status << " " << response->Message << ")");
- if (!response->Status.StartsWith('2') && response->Status != "404") {
- static constexpr size_t MAX_LOGGED_SIZE = 1024;
- LOG_DEBUG_S(ctx, HttpLog,
- "(#"
- << TSocketImpl::GetRawSocket()
- << ","
- << Address
- << ") Request: "
- << request->GetObfuscatedData().substr(0, MAX_LOGGED_SIZE));
- LOG_DEBUG_S(ctx, HttpLog,
- "(#"
- << TSocketImpl::GetRawSocket()
- << ","
- << Address
- << ") Response: "
- << TString(response->GetRawData()).substr(0, MAX_LOGGED_SIZE));
- }
- THolder<TEvHttpProxy::TEvReportSensors> sensors(BuildIncomingRequestSensors(request, response));
- ctx.Send(Endpoint->Owner, sensors.Release());
- if (request == Requests.front() && CurrentResponse == nullptr) {
- CurrentResponse = response;
- return FlushOutput(ctx);
- } else {
- // we are ahead of our pipeline
- Responses.emplace(request, response);
- return true;
- }
- }
-
- bool FlushOutput(const TActorContext& ctx) {
- while (CurrentResponse != nullptr) {
- size_t size = CurrentResponse->Size();
- if (size == 0) {
- Y_ABORT_UNLESS(Requests.front() == CurrentResponse->GetRequest());
- bool close = CurrentResponse->IsConnectionClose();
- Requests.pop_front();
- CleanupResponse(CurrentResponse);
- if (!Requests.empty()) {
- auto it = Responses.find(Requests.front());
- if (it != Responses.end()) {
- CurrentResponse = it->second;
- Responses.erase(it);
- continue;
- } else {
- LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - FlushOutput request not found");
- Die(ctx);
- return false;
- }
- } else {
- if (close) {
- LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed");
- Die(ctx);
- return false;
- } else {
- continue;
- }
- }
- }
- 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;
- }
- if (PollerToken->RequestNotificationAfterWouldBlock(read, write)) {
- continue;
- }
- }
- break;
- } else {
- CleanupResponse(CurrentResponse);
- LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed - error in FlushOutput: " << strerror(-res));
- Die(ctx);
- return false;
- }
- }
- return true;
- }
-
- STFUNC(StateAccepting) {
- switch (ev->GetTypeRewrite()) {
- CFunc(TEvents::TEvBootstrap::EventType, Bootstrap);
- HFunc(TEvPollerReady, HandleAccepting);
- HFunc(TEvPollerRegisterResult, HandleAccepting);
- }
- }
-
- STFUNC(StateConnected) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvPollerReady, HandleConnected);
- HFunc(TEvHttpProxy::TEvHttpOutgoingResponse, HandleConnected);
- HFunc(TEvPollerRegisterResult, HandleConnected);
- }
- }
-};
-
-IActor* CreateIncomingConnectionActor(
- std::shared_ptr<TPrivateEndpointInfo> endpoint,
- TIntrusivePtr<TSocketDescriptor> socket,
- THttpConfig::SocketAddressType address,
- THttpIncomingRequestPtr recycledRequest) {
- if (endpoint->Secure) {
- return new TIncomingConnectionActor<TSecureSocketImpl>(std::move(endpoint), std::move(socket), address, std::move(recycledRequest));
- } else {
- return new TIncomingConnectionActor<TPlainSocketImpl>(std::move(endpoint), std::move(socket), address, std::move(recycledRequest));
- }
-}
-
-}
diff --git a/library/cpp/actors/http/http_proxy_outgoing.cpp b/library/cpp/actors/http/http_proxy_outgoing.cpp
deleted file mode 100644
index b1f27c2c5a..0000000000
--- a/library/cpp/actors/http/http_proxy_outgoing.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-#include "http_proxy.h"
-#include "http_proxy_sock_impl.h"
-
-namespace NHttp {
-
-template <typename TSocketImpl>
-class TOutgoingConnectionActor : public NActors::TActor<TOutgoingConnectionActor<TSocketImpl>>, public TSocketImpl, virtual public THttpConfig {
-public:
- using TBase = NActors::TActor<TOutgoingConnectionActor<TSocketImpl>>;
- using TSelf = TOutgoingConnectionActor<TSocketImpl>;
- const TActorId Owner;
- const TActorId Poller;
- SocketAddressType Address;
- TActorId RequestOwner;
- THttpOutgoingRequestPtr Request;
- THttpIncomingResponsePtr Response;
- TInstant LastActivity;
- TDuration ConnectionTimeout = CONNECTION_TIMEOUT;
- NActors::TPollerToken::TPtr PollerToken;
-
- TOutgoingConnectionActor(const TActorId& owner, const TActorId& poller)
- : TBase(&TSelf::StateWaiting)
- , Owner(owner)
- , Poller(poller)
- {
- }
-
- static constexpr char ActorName[] = "OUT_CONNECTION_ACTOR";
-
- void Die(const NActors::TActorContext& ctx) override {
- ctx.Send(Owner, new TEvHttpProxy::TEvHttpConnectionClosed(ctx.SelfID));
- TSocketImpl::Shutdown(); // to avoid errors when connection already closed
- TBase::Die(ctx);
- }
-
- TString GetSocketName() {
- TStringBuilder builder;
- if (TSocketImpl::Socket) {
- builder << "(#" << TSocketImpl::GetRawSocket();
- if (Address && Address->SockAddr()->sa_family) {
- builder << "," << Address;
- }
- builder << ") ";
- }
- return builder;
- }
-
- void ReplyAndDie(const NActors::TActorContext& ctx) {
- LOG_DEBUG_S(ctx, HttpLog, GetSocketName() << "-> (" << Response->Status << " " << Response->Message << ")");
- ctx.Send(RequestOwner, new TEvHttpProxy::TEvHttpIncomingResponse(Request, Response));
- RequestOwner = TActorId();
- THolder<TEvHttpProxy::TEvReportSensors> sensors(BuildOutgoingRequestSensors(Request, Response));
- ctx.Send(Owner, sensors.Release());
- LOG_DEBUG_S(ctx, HttpLog, GetSocketName() << "connection closed");
- Die(ctx);
- }
-
- void ReplyErrorAndDie(const NActors::TActorContext& ctx, const TString& error) {
- LOG_ERROR_S(ctx, HttpLog, GetSocketName() << "connection closed with error: " << error);
- if (RequestOwner) {
- ctx.Send(RequestOwner, new TEvHttpProxy::TEvHttpIncomingResponse(Request, Response, error));
- RequestOwner = TActorId();
- THolder<TEvHttpProxy::TEvReportSensors> sensors(BuildOutgoingRequestSensors(Request, Response));
- ctx.Send(Owner, sensors.Release());
- Die(ctx);
- }
- }
-
-protected:
- void FailConnection(const NActors::TActorContext& ctx, const TString& error) {
- if (Request) {
- return ReplyErrorAndDie(ctx, error);
- }
- return TBase::Become(&TOutgoingConnectionActor::StateFailed);
- }
-
- void Connect(const NActors::TActorContext& ctx) {
- LOG_DEBUG_S(ctx, HttpLog, GetSocketName() << "connecting");
- TSocketImpl::Create(Address->SockAddr()->sa_family);
- TSocketImpl::SetNonBlock();
- TSocketImpl::SetTimeout(ConnectionTimeout);
- int res = TSocketImpl::Connect(Address);
- RegisterPoller(ctx);
- switch (-res) {
- case 0:
- return OnConnect(ctx);
- case EINPROGRESS:
- case EAGAIN:
- return TBase::Become(&TOutgoingConnectionActor::StateConnecting);
- default:
- return ReplyErrorAndDie(ctx, strerror(-res));
- }
- }
-
- 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);
- if (res > 0) {
- Request->ChopHead(res);
- } else if (-res == EINTR) {
- continue;
- } else if (-res == EAGAIN || -res == EWOULDBLOCK) {
- if (PollerToken) {
- if (!read && !write) {
- write = true;
- }
- if (PollerToken->RequestNotificationAfterWouldBlock(read, write)) {
- continue;
- }
- }
- break;
- } else {
- if (!res) {
- ReplyAndDie(ctx);
- } else {
- ReplyErrorAndDie(ctx, strerror(-res));
- }
- break;
- }
- }
- }
- }
-
- void PullInput(const NActors::TActorContext& ctx) {
- 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);
- 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 (PollerToken->RequestNotificationAfterWouldBlock(read, write)) {
- continue;
- }
- }
- return;
- } else {
- if (!res) {
- Response->ConnectionClosed();
- }
- 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));
- }
-
- 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);
- }
- return;
- } else {
- return ReplyErrorAndDie(ctx, strerror(-res));
- }
- }
- LOG_DEBUG_S(ctx, HttpLog, GetSocketName() << "outgoing connection opened");
- TBase::Become(&TOutgoingConnectionActor::StateConnected);
- LOG_DEBUG_S(ctx, HttpLog, GetSocketName() << "<- (" << Request->Method << " " << Request->URL << ")");
- ctx.Send(ctx.SelfID, new NActors::TEvPollerReady(nullptr, true, true));
- }
-
- static int GetPort(SocketAddressType address) {
- switch (address->SockAddr()->sa_family) {
- case AF_INET:
- return ntohs(reinterpret_cast<sockaddr_in*>(address->SockAddr())->sin_port);
- case AF_INET6:
- return ntohs(reinterpret_cast<sockaddr_in6*>(address->SockAddr())->sin6_port);
- }
- return {};
- }
-
- static void SetPort(SocketAddressType address, int port) {
- switch (address->SockAddr()->sa_family) {
- case AF_INET:
- reinterpret_cast<sockaddr_in*>(address->SockAddr())->sin_port = htons(port);
- break;
- case AF_INET6:
- reinterpret_cast<sockaddr_in6*>(address->SockAddr())->sin6_port = htons(port);
- break;
- }
- }
-
- void HandleResolving(TEvHttpProxy::TEvResolveHostResponse::TPtr event, const NActors::TActorContext& ctx) {
- LastActivity = ctx.Now();
- if (!event->Get()->Error.empty()) {
- return FailConnection(ctx, event->Get()->Error);
- }
- Address = event->Get()->Address;
- if (GetPort(Address) == 0) {
- SetPort(Address, Request->Secure ? 443 : 80);
- }
- Connect(ctx);
- }
-
- void HandleConnecting(NActors::TEvPollerReady::TPtr, const NActors::TActorContext& ctx) {
- LastActivity = ctx.Now();
- int res = TSocketImpl::GetError();
- if (res == 0) {
- OnConnect(ctx);
- } else {
- FailConnection(ctx, TStringBuilder() << strerror(res));
- }
- }
-
- 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) {
- OnConnect(ctx);
- } else {
- FailConnection(ctx, TStringBuilder() << strerror(res));
- }
- }
-
- void HandleWaiting(TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
- LastActivity = ctx.Now();
- Request = std::move(event->Get()->Request);
- TSocketImpl::SetHost(TString(Request->Host));
- LOG_DEBUG_S(ctx, HttpLog, GetSocketName() << "resolving " << TSocketImpl::Host);
- Request->Timer.Reset();
- RequestOwner = event->Sender;
- ctx.Send(Owner, new TEvHttpProxy::TEvResolveHostRequest(TSocketImpl::Host));
- if (event->Get()->Timeout) {
- ConnectionTimeout = event->Get()->Timeout;
- }
- ctx.Schedule(ConnectionTimeout, new NActors::TEvents::TEvWakeup());
- LastActivity = ctx.Now();
- TBase::Become(&TOutgoingConnectionActor::StateResolving);
- }
-
- void HandleConnected(NActors::TEvPollerReady::TPtr event, const NActors::TActorContext& ctx) {
- LastActivity = ctx.Now();
- if (event->Get()->Write && RequestOwner) {
- FlushOutput(ctx);
- }
- if (event->Get()->Read && RequestOwner) {
- PullInput(ctx);
- }
- }
-
- void HandleConnected(NActors::TEvPollerRegisterResult::TPtr ev, const NActors::TActorContext& ctx) {
- PollerToken = std::move(ev->Get()->PollerToken);
- LastActivity = ctx.Now();
- PullInput(ctx);
- FlushOutput(ctx);
- }
-
- void HandleFailed(TEvHttpProxy::TEvHttpOutgoingRequest::TPtr event, const NActors::TActorContext& ctx) {
- Request = std::move(event->Get()->Request);
- RequestOwner = event->Sender;
- ReplyErrorAndDie(ctx, "Failed");
- }
-
- void HandleTimeout(const NActors::TActorContext& ctx) {
- TDuration inactivityTime = ctx.Now() - LastActivity;
- if (inactivityTime >= ConnectionTimeout) {
- FailConnection(ctx, "Connection timed out");
- } else {
- ctx.Schedule(Min(ConnectionTimeout - inactivityTime, TDuration::MilliSeconds(100)), new NActors::TEvents::TEvWakeup());
- }
- }
-
- STFUNC(StateWaiting) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHttpProxy::TEvHttpOutgoingRequest, HandleWaiting);
- CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
- }
- }
-
- STFUNC(StateResolving) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHttpProxy::TEvResolveHostResponse, HandleResolving);
- CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
- }
- }
-
- STFUNC(StateConnecting) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NActors::TEvPollerReady, HandleConnecting);
- CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
- HFunc(NActors::TEvPollerRegisterResult, HandleConnecting);
- }
- }
-
- STFUNC(StateConnected) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NActors::TEvPollerReady, HandleConnected);
- CFunc(NActors::TEvents::TEvWakeup::EventType, HandleTimeout);
- HFunc(NActors::TEvPollerRegisterResult, HandleConnected);
- }
- }
-
- STFUNC(StateFailed) {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvHttpProxy::TEvHttpOutgoingRequest, HandleFailed);
- }
- }
-};
-
-NActors::IActor* CreateOutgoingConnectionActor(const TActorId& owner, bool secure, const TActorId& poller) {
- if (secure) {
- return new TOutgoingConnectionActor<TSecureSocketImpl>(owner, poller);
- } else {
- return new TOutgoingConnectionActor<TPlainSocketImpl>(owner, poller);
- }
-}
-
-}
diff --git a/library/cpp/actors/http/http_proxy_sock64.h b/library/cpp/actors/http/http_proxy_sock64.h
deleted file mode 100644
index fa6d9a1e56..0000000000
--- a/library/cpp/actors/http/http_proxy_sock64.h
+++ /dev/null
@@ -1,147 +0,0 @@
-#pragma once
-#include <util/network/sock.h>
-#include "http.h"
-
-class TInet64StreamSocket: public TStreamSocket {
-protected:
- TInet64StreamSocket(const TInet64StreamSocket& parent, SOCKET fd)
- : TStreamSocket(fd)
- , AF(parent.AF)
- {
- }
-
-public:
- TInet64StreamSocket(int af = {}) {
- CreateSocket(af);
- }
-
- std::shared_ptr<ISockAddr> MakeAddress(const TString& address, int port) {
- if (!address) {
- if (AF == AF_INET6) {
- return std::make_shared<TSockAddrInet6>("::", port);
- } else {
- return std::make_shared<TSockAddrInet>(INADDR_ANY, port);
- }
- }
- if (NHttp::IsIPv6(address)) {
- return std::make_shared<TSockAddrInet6>(address.data(), port);
- } else if (NHttp::IsIPv4(address)) {
- return std::make_shared<TSockAddrInet>(address.data(), port);
- }
- struct addrinfo hints = {
- .ai_flags = AI_PASSIVE,
- .ai_family = AF,
- .ai_socktype = SOCK_STREAM,
- };
- struct addrinfo* gai_res = nullptr;
- int gai_ret = getaddrinfo(address.data(), nullptr, &hints, &gai_res);
- std::shared_ptr<ISockAddr> result;
- if (gai_ret == 0 && gai_res->ai_addr) {
- switch (gai_res->ai_addr->sa_family) {
- case AF_INET6: {
- std::shared_ptr<TSockAddrInet6> resultIp6 = std::make_shared<TSockAddrInet6>();
- if (resultIp6->Size() >= gai_res->ai_addrlen) {
- memcpy(resultIp6->SockAddr(), gai_res->ai_addr, gai_res->ai_addrlen);
- resultIp6->SetPort(port);
- result = std::move(resultIp6);
- }
- }
- break;
- case AF_INET: {
- std::shared_ptr<TSockAddrInet> resultIp4 = std::make_shared<TSockAddrInet>();
- if (resultIp4->Size() >= gai_res->ai_addrlen) {
- memcpy(resultIp4->SockAddr(), gai_res->ai_addr, gai_res->ai_addrlen);
- resultIp4->SetPort(port);
- result = std::move(resultIp4);
- }
- }
- break;
- }
- }
- if (gai_res) {
- freeaddrinfo(gai_res);
- }
- if (result) {
- return result;
- }
- throw yexception() << "Unable to resolve address " << address;
- }
-
- static int GuessAddressFamily(const TString& address) {
- if (!address) {
- return 0;
- }
- if (NHttp::IsIPv6(address)) {
- return AF_INET6;
- } else if (NHttp::IsIPv4(address)) {
- return AF_INET;
- }
- struct addrinfo hints = {
- .ai_flags = AI_PASSIVE,
- .ai_family = 0,
- .ai_socktype = SOCK_STREAM,
- };
- int result = 0;
- struct addrinfo* gai_res = nullptr;
- int gai_ret = getaddrinfo(address.data(), nullptr, &hints, &gai_res);
- if (gai_ret == 0 && gai_res->ai_addr) {
- switch (gai_res->ai_addr->sa_family) {
- case AF_INET:
- case AF_INET6:
- result = gai_res->ai_addr->sa_family;
- break;
- }
- }
- if (gai_res) {
- freeaddrinfo(gai_res);
- }
- return result;
- }
-
- static std::shared_ptr<ISockAddr> MakeAddress(const sockaddr_storage& storage) {
- std::shared_ptr<ISockAddr> addr;
- switch (storage.ss_family) {
- case AF_INET:
- addr = std::make_shared<TSockAddrInet>();
- break;
- case AF_INET6:
- addr = std::make_shared<TSockAddrInet6>();
- break;
- }
- if (addr) {
- memcpy(addr->SockAddr(), &storage, addr->Size());
- }
- return addr;
- }
-
- std::optional<TInet64StreamSocket> Accept(std::shared_ptr<ISockAddr>& acceptedAddr) {
- sockaddr_storage addrStorage = {};
- socklen_t addrLen = sizeof(addrStorage);
- SOCKET s = accept((SOCKET)*this, reinterpret_cast<sockaddr*>(&addrStorage), &addrLen);
- if (s == INVALID_SOCKET) {
- return {};
- }
- acceptedAddr = MakeAddress(addrStorage);
- return TInet64StreamSocket(*this, s);
- }
-
-protected:
- int AF = AF_UNSPEC;
-
- void CreateSocket(int af) {
- SOCKET s;
- if (af == 0) {
- s = socket(AF = AF_INET6, SOCK_STREAM, 0);
- if (s < 0) {
- s = socket(AF = AF_INET, SOCK_STREAM, 0);
- }
- } else {
- s = socket(AF = af, SOCK_STREAM, 0);
- }
- if (AF == AF_INET6) {
- SetSockOpt(s, SOL_SOCKET, IPV6_V6ONLY, (int)false);
- }
- TSocketHolder sock(s);
- sock.Swap(*this);
- }
-};
diff --git a/library/cpp/actors/http/http_proxy_sock_impl.h b/library/cpp/actors/http/http_proxy_sock_impl.h
deleted file mode 100644
index 788c99d9b2..0000000000
--- a/library/cpp/actors/http/http_proxy_sock_impl.h
+++ /dev/null
@@ -1,274 +0,0 @@
-#pragma once
-
-#include "http.h"
-#include "http_proxy.h"
-
-namespace NHttp {
-
-struct TPlainSocketImpl : virtual public THttpConfig {
- TIntrusivePtr<TSocketDescriptor> Socket;
- TString Host;
-
- TPlainSocketImpl() = default;
-
- void Create(int af) {
- Socket = new TSocketDescriptor(af);
- }
-
- TPlainSocketImpl(TIntrusivePtr<TSocketDescriptor> socket)
- : Socket(std::move(socket))
- {}
-
- SOCKET GetRawSocket() const {
- return static_cast<SOCKET>(Socket->Socket);
- }
-
- void SetNonBlock(bool nonBlock = true) noexcept {
- try {
- ::SetNonBlock(Socket->Socket, nonBlock);
- }
- catch (const yexception&) {
- }
- }
-
- void SetTimeout(TDuration timeout) noexcept {
- try {
- ::SetSocketTimeout(Socket->Socket, timeout.Seconds(), timeout.MilliSecondsOfSecond());
- }
- catch (const yexception&) {
- }
- }
-
- void Shutdown() {
- //Socket->Socket.ShutDown(SHUT_RDWR); // KIKIMR-3895
- if (Socket) {
- ::shutdown(Socket->Socket, SHUT_RDWR);
- }
- }
-
- int Connect(SocketAddressType address) {
- return Socket->Socket.Connect(address.get());
- }
-
- static constexpr int OnConnect(bool&, bool&) {
- return 1;
- }
-
- static int OnAccept(std::shared_ptr<TPrivateEndpointInfo>, bool&, bool&) {
- return 1;
- }
-
- bool IsGood() {
- int res;
- GetSockOpt(Socket->Socket, SOL_SOCKET, SO_ERROR, res);
- return res == 0;
- }
-
- int GetError() {
- int res;
- GetSockOpt(Socket->Socket, SOL_SOCKET, SO_ERROR, res);
- return res;
- }
-
- 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&) {
- return Socket->Socket.Recv(data, size);
- }
-
- void SetHost(const TString& host) {
- Host = host;
- }
-};
-
-struct TSecureSocketImpl : TPlainSocketImpl, TSslHelpers {
- static TSecureSocketImpl* IO(BIO* bio) noexcept {
- return static_cast<TSecureSocketImpl*>(BIO_get_data(bio));
- }
-
- static int IoWrite(BIO* bio, const char* data, int dlen) noexcept {
- BIO_clear_retry_flags(bio);
- int res = IO(bio)->Socket->Socket.Send(data, dlen);
- if (-res == EAGAIN) {
- BIO_set_retry_write(bio);
- }
- return res;
- }
-
- static int IoRead(BIO* bio, char* data, int dlen) noexcept {
- BIO_clear_retry_flags(bio);
- int res = IO(bio)->Socket->Socket.Recv(data, dlen);
- if (-res == EAGAIN) {
- BIO_set_retry_read(bio);
- }
- return res;
- }
-
- static int IoPuts(BIO* bio, const char* buf) noexcept {
- Y_UNUSED(bio);
- Y_UNUSED(buf);
- return -2;
- }
-
- static int IoGets(BIO* bio, char* buf, int size) noexcept {
- Y_UNUSED(bio);
- Y_UNUSED(buf);
- Y_UNUSED(size);
- return -2;
- }
-
- static long IoCtrl(BIO* bio, int cmd, long larg, void* parg) noexcept {
- Y_UNUSED(larg);
- Y_UNUSED(parg);
-
- if (cmd == BIO_CTRL_FLUSH) {
- IO(bio)->Flush();
- return 1;
- }
-
- return -2;
- }
-
- static int IoCreate(BIO* bio) noexcept {
- BIO_set_data(bio, nullptr);
- BIO_set_init(bio, 1);
- return 1;
- }
-
- static int IoDestroy(BIO* bio) noexcept {
- BIO_set_data(bio, nullptr);
- BIO_set_init(bio, 0);
- return 1;
- }
-
- static BIO_METHOD* CreateIoMethod() {
- BIO_METHOD* method = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "SecureSocketImpl");
- BIO_meth_set_write(method, IoWrite);
- BIO_meth_set_read(method, IoRead);
- BIO_meth_set_puts(method, IoPuts);
- BIO_meth_set_gets(method, IoGets);
- BIO_meth_set_ctrl(method, IoCtrl);
- BIO_meth_set_create(method, IoCreate);
- BIO_meth_set_destroy(method, IoDestroy);
- return method;
- }
-
- static BIO_METHOD* IoMethod() {
- static BIO_METHOD* method = CreateIoMethod();
- return method;
- }
-
- TSslHolder<BIO> Bio;
- TSslHolder<SSL_CTX> Ctx;
- TSslHolder<SSL> Ssl;
-
- TSecureSocketImpl() = default;
-
- TSecureSocketImpl(TIntrusivePtr<TSocketDescriptor> socket)
- : TPlainSocketImpl(std::move(socket))
- {}
-
- void InitClientSsl() {
- Bio.Reset(BIO_new(IoMethod()));
- BIO_set_data(Bio.Get(), this);
- BIO_set_nbio(Bio.Get(), 1);
- Ctx = CreateClientContext();
- Ssl = ConstructSsl(Ctx.Get(), Bio.Get());
- if (!Host.Empty()) {
- SSL_set_tlsext_host_name(Ssl.Get(), Host.c_str());
- }
- SSL_set_connect_state(Ssl.Get());
- }
-
- void InitServerSsl(SSL_CTX* ctx) {
- Bio.Reset(BIO_new(IoMethod()));
- BIO_set_data(Bio.Get(), this);
- BIO_set_nbio(Bio.Get(), 1);
- Ssl = ConstructSsl(ctx, Bio.Get());
- SSL_set_accept_state(Ssl.Get());
- }
-
- void Flush() {}
-
- 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;
- case SSL_ERROR_WANT_WRITE:
- write = true;
- return -EAGAIN;
- default:
- return -EIO;
- }
- }
- return res;
- }
-
- 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;
- case SSL_ERROR_WANT_WRITE:
- write = true;
- return -EAGAIN;
- default:
- return -EIO;
- }
- }
- return res;
- }
-
- int OnConnect(bool& read, bool& write) {
- if (!Ssl) {
- InitClientSsl();
- }
- int res = SSL_connect(Ssl.Get());
- if (res <= 0) {
- res = SSL_get_error(Ssl.Get(), res);
- switch(res) {
- case SSL_ERROR_WANT_READ:
- read = true;
- return -EAGAIN;
- case SSL_ERROR_WANT_WRITE:
- write = true;
- return -EAGAIN;
- default:
- return -EIO;
- }
- }
- return res;
- }
-
- int OnAccept(std::shared_ptr<TPrivateEndpointInfo> endpoint, bool& read, bool& write) {
- if (!Ssl) {
- InitServerSsl(endpoint->SecureContext.Get());
- }
- int res = SSL_accept(Ssl.Get());
- if (res <= 0) {
- res = SSL_get_error(Ssl.Get(), res);
- switch(res) {
- case SSL_ERROR_WANT_READ:
- read = true;
- return -EAGAIN;
- case SSL_ERROR_WANT_WRITE:
- write = true;
- return -EAGAIN;
- default:
- return -EIO;
- }
- }
- return res;
- }
-};
-
-}
diff --git a/library/cpp/actors/http/http_proxy_ssl.h b/library/cpp/actors/http/http_proxy_ssl.h
deleted file mode 100644
index 9953430b1c..0000000000
--- a/library/cpp/actors/http/http_proxy_ssl.h
+++ /dev/null
@@ -1,133 +0,0 @@
-#pragma once
-
-#include <openssl/bio.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/tls1.h>
-
-namespace NHttp {
-
-struct TSslHelpers {
- struct TSslDestroy {
- static void Destroy(SSL_CTX* ctx) noexcept {
- SSL_CTX_free(ctx);
- }
-
- static void Destroy(SSL* ssl) noexcept {
- SSL_free(ssl);
- }
-
- static void Destroy(X509* cert) noexcept {
- X509_free(cert);
- }
-
- static void Destroy(EVP_PKEY* pkey) noexcept {
- EVP_PKEY_free(pkey);
- }
-
- static void Destroy(BIO* bio) noexcept {
- BIO_free(bio);
- }
- };
-
- template <typename T>
- using TSslHolder = THolder<T, TSslDestroy>;
-
- static TSslHolder<SSL_CTX> CreateSslCtx(const SSL_METHOD* method) {
- TSslHolder<SSL_CTX> ctx(SSL_CTX_new(method));
-
- if (ctx) {
- SSL_CTX_set_options(ctx.Get(), SSL_OP_NO_SSLv2);
- SSL_CTX_set_options(ctx.Get(), SSL_OP_NO_SSLv3);
- SSL_CTX_set_options(ctx.Get(), SSL_OP_NO_TLSv1);
- SSL_CTX_set_options(ctx.Get(), SSL_OP_NO_TLSv1_1);
- SSL_CTX_set_options(ctx.Get(), SSL_OP_MICROSOFT_SESS_ID_BUG);
- SSL_CTX_set_options(ctx.Get(), SSL_OP_NETSCAPE_CHALLENGE_BUG);
- }
-
- return ctx;
- }
-
- static TSslHolder<SSL_CTX> CreateClientContext() {
- return CreateSslCtx(SSLv23_client_method());
- }
-
- static TSslHolder<SSL_CTX> CreateServerContext(const TString& certificate, const TString& key) {
- TSslHolder<SSL_CTX> ctx = CreateSslCtx(SSLv23_server_method());
- SSL_CTX_set_ecdh_auto(ctx.Get(), 1);
- int res;
- res = SSL_CTX_use_certificate_chain_file(ctx.Get(), certificate.c_str());
- if (res < 0) {
- // TODO(xenoxeno): more diagnostics?
- return nullptr;
- }
- res = SSL_CTX_use_PrivateKey_file(ctx.Get(), key.c_str(), SSL_FILETYPE_PEM);
- if (res < 0) {
- // TODO(xenoxeno): more diagnostics?
- return nullptr;
- }
- return ctx;
- }
-
- static bool LoadX509Chain(TSslHolder<SSL_CTX>& ctx, const TString& pem) {
- TSslHolder<BIO> bio(BIO_new_mem_buf(pem.c_str(), pem.size()));
- if (bio == nullptr) {
- return false;
- }
- TSslHolder<X509> cert(PEM_read_bio_X509_AUX(bio.Get(), nullptr, nullptr, nullptr));
- if (cert == nullptr) {
- return false;
- }
- if (SSL_CTX_use_certificate(ctx.Get(), cert.Release()) <= 0) {
- return false;
- }
- SSL_CTX_clear_chain_certs(ctx.Get());
- while (true) {
- TSslHolder<X509> ca(PEM_read_bio_X509(bio.Get(), nullptr, nullptr, nullptr));
- if (ca == nullptr) {
- break;
- }
- if (!SSL_CTX_add0_chain_cert(ctx.Get(), ca.Release())) {
- return false;
- }
- }
- return true;
- }
-
- static bool LoadPrivateKey(TSslHolder<SSL_CTX>& ctx, const TString& pem) {
- TSslHolder<BIO> bio(BIO_new_mem_buf(pem.c_str(), pem.size()));
- if (bio == nullptr) {
- return false;
- }
- TSslHolder<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(bio.Get(), nullptr, nullptr, nullptr));
- if (SSL_CTX_use_PrivateKey(ctx.Get(), pkey.Release()) <= 0) {
- return false;
- }
- return true;
- }
-
- static TSslHolder<SSL_CTX> CreateServerContext(const TString& pem) {
- TSslHolder<SSL_CTX> ctx = CreateSslCtx(SSLv23_server_method());
- SSL_CTX_set_ecdh_auto(ctx.Get(), 1);
- if (!LoadX509Chain(ctx, pem)) {
- return nullptr;
- }
- if (!LoadPrivateKey(ctx, pem)) {
- return nullptr;
- }
- return ctx;
- }
-
- static TSslHolder<SSL> ConstructSsl(SSL_CTX* ctx, BIO* bio) {
- TSslHolder<SSL> ssl(SSL_new(ctx));
-
- if (ssl) {
- BIO_up_ref(bio); // SSL_set_bio consumes only one reference if rbio and wbio are the same
- SSL_set_bio(ssl.Get(), bio, bio);
- }
-
- return ssl;
- }
-};
-
-}
diff --git a/library/cpp/actors/http/http_static.cpp b/library/cpp/actors/http/http_static.cpp
deleted file mode 100644
index ff36f5486d..0000000000
--- a/library/cpp/actors/http/http_static.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-#include "http_proxy.h"
-#include "http_static.h"
-#include <library/cpp/actors/core/executor_pool_basic.h>
-#include <library/cpp/actors/core/log.h>
-#include <library/cpp/actors/core/scheduler_basic.h>
-#include <library/cpp/actors/http/http.h>
-#include <library/cpp/resource/resource.h>
-#include <util/folder/path.h>
-#include <util/stream/file.h>
-
-namespace NHttp {
-
-class THttpStaticContentHandler : public NActors::TActor<THttpStaticContentHandler> {
-public:
- using TBase = NActors::TActor<THttpStaticContentHandler>;
- const TFsPath URL;
- const TFsPath FilePath;
- const TFsPath ResourcePath;
- const TFsPath Index;
-
- THttpStaticContentHandler(const TString& url, const TString& filePath, const TString& resourcePath, const TString& index)
- : TBase(&THttpStaticContentHandler::StateWork)
- , URL(url)
- , FilePath(filePath)
- , ResourcePath(resourcePath)
- , Index(index)
- {}
-
- static constexpr char ActorName[] = "HTTP_STATIC_ACTOR";
-
- static TInstant GetCompileTime() {
- tm compileTime;
- strptime(__DATE__ " " __TIME__, "%B %d %Y %H:%M:%S", &compileTime);
- return TInstant::Seconds(mktime(&compileTime));
- }
-
- void Handle(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) {
- THttpOutgoingResponsePtr response;
- if (event->Get()->Request->Method != "GET") {
- response = event->Get()->Request->CreateResponseBadRequest("Wrong request");
- ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- return;
- }
- TFsPath url(event->Get()->Request->URL.Before('?'));
- if (!url.IsAbsolute()) {
- response = event->Get()->Request->CreateResponseBadRequest("Completely wrong URL");
- ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- return;
- }
- if (url.GetPath().EndsWith('/') && Index.IsDefined()) {
- url /= Index;
- }
- url = url.RelativeTo(URL);
- try {
- // TODO: caching?
- TString contentType = mimetypeByExt(url.GetExtension().c_str());
- TString data;
- TFileStat filestat;
- TFsPath resourcename(ResourcePath / url);
- if (NResource::FindExact(resourcename.GetPath(), &data)) {
- static TInstant compileTime(GetCompileTime());
- filestat.MTime = compileTime.Seconds();
- } else {
- TFsPath filename(FilePath / url);
- if (!filename.IsSubpathOf(FilePath) && filename != FilePath) {
- response = event->Get()->Request->CreateResponseBadRequest("Wrong URL");
- ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- return;
- }
- if (filename.Stat(filestat) && filestat.IsFile()) {
- data = TUnbufferedFileInput(filename).ReadAll();
- }
- }
- if (!filestat.IsNull()) {
- response = event->Get()->Request->CreateResponseOK(data, contentType, TInstant::Seconds(filestat.MTime));
- } else {
- response = event->Get()->Request->CreateResponseNotFound("File not found");
- }
- }
- catch (const yexception&) {
- response = event->Get()->Request->CreateResponseServiceUnavailable("Not available");
- }
- ctx.Send(event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
- }
-
- STFUNC(StateWork) {
- switch (ev->GetTypeRewrite()) {
- HFunc(NHttp::TEvHttpProxy::TEvHttpIncomingRequest, Handle);
- }
- }
-};
-
-NActors::IActor* CreateHttpStaticContentHandler(const TString& url, const TString& filePath, const TString& resourcePath, const TString& index) {
- return new THttpStaticContentHandler(url, filePath, resourcePath, index);
-}
-
-}
diff --git a/library/cpp/actors/http/http_static.h b/library/cpp/actors/http/http_static.h
deleted file mode 100644
index f91e15dfb1..0000000000
--- a/library/cpp/actors/http/http_static.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-#include <library/cpp/actors/core/actor.h>
-#include "http.h"
-
-namespace NHttp {
-
-NActors::IActor* CreateHttpStaticContentHandler(const TString& url, const TString& filePath, const TString& resourcePath, const TString& index = TString());
-
-}
diff --git a/library/cpp/actors/http/http_ut.cpp b/library/cpp/actors/http/http_ut.cpp
deleted file mode 100644
index e06de07867..0000000000
--- a/library/cpp/actors/http/http_ut.cpp
+++ /dev/null
@@ -1,509 +0,0 @@
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/testing/unittest/tests_data.h>
-#include <library/cpp/actors/core/executor_pool_basic.h>
-#include <library/cpp/actors/core/scheduler_basic.h>
-#include <library/cpp/actors/testlib/test_runtime.h>
-#include <util/system/tempfile.h>
-#include "http.h"
-#include "http_proxy.h"
-
-
-
-enum EService : NActors::NLog::EComponent {
- MIN,
- Logger,
- MVP,
- MAX
-};
-
-namespace {
-
-template <typename HttpType>
-void EatWholeString(TIntrusivePtr<HttpType>& request, const TString& data) {
- request->EnsureEnoughSpaceAvailable(data.size());
- auto size = std::min(request->Avail(), data.size());
- memcpy(request->Pos(), data.data(), size);
- request->Advance(size);
-}
-
-template <typename HttpType>
-void EatPartialString(TIntrusivePtr<HttpType>& request, const TString& data) {
- for (char c : data) {
- request->EnsureEnoughSpaceAvailable(1);
- memcpy(request->Pos(), &c, 1);
- request->Advance(1);
- }
-}
-
-}
-
-Y_UNIT_TEST_SUITE(HttpProxy) {
- Y_UNIT_TEST(BasicParsing) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatWholeString(request, "GET /test HTTP/1.1\r\nHost: test\r\nSome-Header: 32344\r\n\r\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "GET");
- UNIT_ASSERT_EQUAL(request->URL, "/test");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->Host, "test");
- UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
- }
-
- Y_UNIT_TEST(GetWithSpecifiedContentType) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatWholeString(request, "GET /test HTTP/1.1\r\nHost: test\r\nContent-Type: application/json\r\nSome-Header: 32344\r\n\r\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "GET");
- UNIT_ASSERT_EQUAL(request->URL, "/test");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->Host, "test");
- UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nContent-Type: application/json\r\nSome-Header: 32344\r\n\r\n");
- }
-
- Y_UNIT_TEST(BasicParsingChunkedBodyRequest) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatWholeString(request, "POST /Url HTTP/1.1\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nthis\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "POST");
- UNIT_ASSERT_EQUAL(request->URL, "/Url");
- UNIT_ASSERT_EQUAL(request->Connection, "close");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->TransferEncoding, "chunked");
- UNIT_ASSERT_EQUAL(request->Body, "this is test.");
- }
-
- Y_UNIT_TEST(BasicPost) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatWholeString(request, "POST /Url HTTP/1.1\r\nConnection: close\r\nContent-Length: 13\r\n\r\nthis is test.");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "POST");
- UNIT_ASSERT_EQUAL(request->URL, "/Url");
- UNIT_ASSERT_EQUAL(request->Connection, "close");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->TransferEncoding, "");
- UNIT_ASSERT_EQUAL(request->Body, "this is test.");
- }
-
- Y_UNIT_TEST(BasicParsingChunkedBodyResponse) {
- NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
- NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
- EatWholeString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nthis\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
- UNIT_ASSERT_EQUAL(response->Stage, NHttp::THttpIncomingResponse::EParseStage::Done);
- UNIT_ASSERT_EQUAL(response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Connection, "close");
- UNIT_ASSERT_EQUAL(response->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(response->Version, "1.1");
- UNIT_ASSERT_EQUAL(response->TransferEncoding, "chunked");
- UNIT_ASSERT_EQUAL(response->Body, "this is test.");
- }
-
- Y_UNIT_TEST(InvalidParsingChunkedBody) {
- NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
- NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
- EatWholeString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nthis\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
- UNIT_ASSERT(response->IsError());
- }
-
- Y_UNIT_TEST(AdvancedParsingChunkedBody) {
- NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
- NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
- EatWholeString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n6\r\nthis\r\n\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
- UNIT_ASSERT_EQUAL(response->Stage, NHttp::THttpIncomingResponse::EParseStage::Done);
- UNIT_ASSERT_EQUAL(response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Connection, "close");
- UNIT_ASSERT_EQUAL(response->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(response->Version, "1.1");
- UNIT_ASSERT_EQUAL(response->TransferEncoding, "chunked");
- UNIT_ASSERT_EQUAL(response->Body, "this\r\n is test.");
- }
-
- Y_UNIT_TEST(CreateCompressedResponse) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatWholeString(request, "GET /Url HTTP/1.1\r\nConnection: close\r\nAccept-Encoding: gzip, deflate\r\n\r\n");
- NHttp::THttpOutgoingResponsePtr response = new NHttp::THttpOutgoingResponse(request, "HTTP", "1.1", "200", "OK");
- TString compressedBody = "something very long to compress with deflate algorithm. something very long to compress with deflate algorithm.";
- response->EnableCompression();
- size_t size1 = response->Size();
- response->SetBody(compressedBody);
- size_t size2 = response->Size();
- size_t compressedBodySize = size2 - size1;
- UNIT_ASSERT_VALUES_EQUAL("deflate", response->ContentEncoding);
- UNIT_ASSERT(compressedBodySize < compressedBody.size());
- NHttp::THttpOutgoingResponsePtr response2 = response->Duplicate(request);
- UNIT_ASSERT_VALUES_EQUAL(response->Body, response2->Body);
- UNIT_ASSERT_VALUES_EQUAL(response->ContentLength, response2->ContentLength);
- UNIT_ASSERT_VALUES_EQUAL(response->Size(), response2->Size());
- }
-
- Y_UNIT_TEST(BasicPartialParsing) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatPartialString(request, "GET /test HTTP/1.1\r\nHost: test\r\nSome-Header: 32344\r\n\r\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "GET");
- UNIT_ASSERT_EQUAL(request->URL, "/test");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->Host, "test");
- UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
- }
-
- Y_UNIT_TEST(BasicPartialParsingChunkedBody) {
- NHttp::THttpOutgoingRequestPtr request = nullptr; //new NHttp::THttpOutgoingRequest();
- NHttp::THttpIncomingResponsePtr response = new NHttp::THttpIncomingResponse(request);
- EatPartialString(response, "HTTP/1.1 200 OK\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nthis\r\n4\r\n is \r\n5\r\ntest.\r\n0\r\n\r\n");
- UNIT_ASSERT_EQUAL(response->Stage, NHttp::THttpIncomingResponse::EParseStage::Done);
- UNIT_ASSERT_EQUAL(response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Connection, "close");
- UNIT_ASSERT_EQUAL(response->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(response->Version, "1.1");
- UNIT_ASSERT_EQUAL(response->TransferEncoding, "chunked");
- UNIT_ASSERT_EQUAL(response->Body, "this is test.");
- }
-
- Y_UNIT_TEST(BasicParsingContentLength0) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatPartialString(request, "GET /test HTTP/1.1\r\nHost: test\r\nContent-Length: 0\r\n\r\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "GET");
- UNIT_ASSERT_EQUAL(request->URL, "/test");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->Host, "test");
- UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nContent-Length: 0\r\n\r\n");
- }
-
- Y_UNIT_TEST(AdvancedParsing) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatWholeString(request, "GE");
- EatWholeString(request, "T");
- EatWholeString(request, " ");
- EatWholeString(request, "/test");
- EatWholeString(request, " HTTP/1.1\r");
- EatWholeString(request, "\nHo");
- EatWholeString(request, "st: test");
- EatWholeString(request, "\r\n");
- EatWholeString(request, "Some-Header: 32344\r\n\r");
- EatWholeString(request, "\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "GET");
- UNIT_ASSERT_EQUAL(request->URL, "/test");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->Host, "test");
- UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
- }
-
- Y_UNIT_TEST(AdvancedPartialParsing) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatPartialString(request, "GE");
- EatPartialString(request, "T");
- EatPartialString(request, " ");
- EatPartialString(request, "/test");
- EatPartialString(request, " HTTP/1.1\r");
- EatPartialString(request, "\nHo");
- EatPartialString(request, "st: test");
- EatPartialString(request, "\r\n");
- EatPartialString(request, "Some-Header: 32344\r\n\r");
- EatPartialString(request, "\n");
- UNIT_ASSERT_EQUAL(request->Stage, NHttp::THttpIncomingRequest::EParseStage::Done);
- UNIT_ASSERT_EQUAL(request->Method, "GET");
- UNIT_ASSERT_EQUAL(request->URL, "/test");
- UNIT_ASSERT_EQUAL(request->Protocol, "HTTP");
- UNIT_ASSERT_EQUAL(request->Version, "1.1");
- UNIT_ASSERT_EQUAL(request->Host, "test");
- UNIT_ASSERT_EQUAL(request->Headers, "Host: test\r\nSome-Header: 32344\r\n\r\n");
- }
-
- Y_UNIT_TEST(BasicRenderBodyWithHeadersAndCookies) {
- NHttp::THttpOutgoingRequestPtr request = NHttp::THttpOutgoingRequest::CreateRequestGet("http://www.yandex.ru/data/url");
- NHttp::THeadersBuilder headers;
- NHttp::TCookiesBuilder cookies;
- cookies.Set("cookie1", "123456");
- cookies.Set("cookie2", "45678");
- headers.Set("Cookie", cookies.Render());
- request->Set(headers);
- TString requestData = request->AsString();
- UNIT_ASSERT_VALUES_EQUAL(requestData, "GET /data/url HTTP/1.1\r\nHost: www.yandex.ru\r\nAccept: */*\r\nCookie: cookie1=123456; cookie2=45678;\r\n");
- }
-
- Y_UNIT_TEST(BasicRenderOutgoingResponse) {
- NHttp::THttpIncomingRequestPtr request = new NHttp::THttpIncomingRequest();
- EatWholeString(request, "GET /test HTTP/1.1\r\nHost: test\r\nSome-Header: 32344\r\n\r\n");
-
- NHttp::THttpOutgoingResponsePtr httpResponseOk = request->CreateResponseOK("response ok");
- UNIT_ASSERT_EQUAL(httpResponseOk->Stage, NHttp::THttpOutgoingResponse::ERenderStage::Done);
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseOk->Status, "200");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseOk->Message, "OK");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseOk->ContentType, "text/html");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseOk->Body, "response ok");
-
- NHttp::THttpOutgoingResponsePtr httpResponseBadRequest = request->CreateResponseBadRequest();
- UNIT_ASSERT_EQUAL(httpResponseBadRequest->Stage, NHttp::THttpOutgoingResponse::ERenderStage::Done);
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseBadRequest->Status, "400");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseBadRequest->Message, "Bad Request");
- UNIT_ASSERT(httpResponseBadRequest->ContentType.empty());
- UNIT_ASSERT(httpResponseBadRequest->Body.empty());
-
- NHttp::THttpOutgoingResponsePtr httpResponseNotFound = request->CreateResponseNotFound();
- UNIT_ASSERT_EQUAL(httpResponseNotFound->Stage, NHttp::THttpOutgoingResponse::ERenderStage::Done);
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseNotFound->Status, "404");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseNotFound->Message, "Not Found");
- UNIT_ASSERT(httpResponseNotFound->ContentType.empty());
- UNIT_ASSERT(httpResponseNotFound->Body.empty());
-
- NHttp::THttpOutgoingResponsePtr httpResponseServiceUnavailable = request->CreateResponseServiceUnavailable();
- UNIT_ASSERT_EQUAL(httpResponseServiceUnavailable->Stage, NHttp::THttpOutgoingResponse::ERenderStage::Done);
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseServiceUnavailable->Status, "503");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseServiceUnavailable->Message, "Service Unavailable");
- UNIT_ASSERT(httpResponseServiceUnavailable->ContentType.empty());
- UNIT_ASSERT(httpResponseServiceUnavailable->Body.empty());
-
- NHttp::THttpOutgoingResponsePtr httpResponseGatewayTimeout = request->CreateResponseGatewayTimeout("gateway timeout body");
- UNIT_ASSERT_EQUAL(httpResponseGatewayTimeout->Stage, NHttp::THttpOutgoingResponse::ERenderStage::Done);
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseGatewayTimeout->Status, "504");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseGatewayTimeout->Message, "Gateway Timeout");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseGatewayTimeout->ContentType, "text/html");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseGatewayTimeout->Body, "gateway timeout body");
-
- NHttp::THttpOutgoingResponsePtr httpIncompleteResponse = request->CreateIncompleteResponse("401", "Unauthorized");
- UNIT_ASSERT_EQUAL(httpIncompleteResponse->Stage, NHttp::THttpOutgoingResponse::ERenderStage::Header);
- UNIT_ASSERT_STRINGS_EQUAL(httpIncompleteResponse->Status, "401");
- UNIT_ASSERT_STRINGS_EQUAL(httpIncompleteResponse->Message, "Unauthorized");
-
- NHttp::THttpOutgoingResponsePtr httpResponse = request->CreateResponse("401", "Unauthorized");
- UNIT_ASSERT_EQUAL(httpResponse->Stage, NHttp::THttpOutgoingResponse::ERenderStage::Done);
- UNIT_ASSERT_STRINGS_EQUAL(httpResponse->Status, "401");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponse->Message, "Unauthorized");
-
- NHttp::THeadersBuilder headers;
- NHttp::TCookiesBuilder cookies;
- cookies.Set("cookie1", "123456");
- headers.Set("Set-Cookie", cookies.Render());
- headers.Set("Location", "http://www.yandex.ru/data/url");
-
- NHttp::THttpOutgoingResponsePtr httpResponseRedirect = request->CreateResponse("302", "Found", headers);
- UNIT_ASSERT_EQUAL(httpResponseRedirect->Stage, NHttp::THttpOutgoingResponse::ERenderStage::Done);
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseRedirect->Status, "302");
- UNIT_ASSERT_STRINGS_EQUAL(httpResponseRedirect->Message, "Found");
- UNIT_ASSERT_STRING_CONTAINS(httpResponseRedirect->Headers, "Set-Cookie: cookie1=123456;");
- UNIT_ASSERT_STRING_CONTAINS(httpResponseRedirect->Headers, "Location: http://www.yandex.ru/data/url");
- }
-
- Y_UNIT_TEST(BasicRunning4) {
- NActors::TTestActorRuntimeBase actorSystem;
- TPortManager portManager;
- TIpPort port = portManager.GetTcpPort();
- TAutoPtr<NActors::IEventHandle> handle;
- actorSystem.Initialize();
- //actorSystem.SetLogPriority(NActorsServices::HTTP, NActors::NLog::PRI_DEBUG);
-
- NActors::IActor* proxy = NHttp::CreateHttpProxy();
- NActors::TActorId proxyId = actorSystem.Register(proxy);
- actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), new NHttp::TEvHttpProxy::TEvAddListeningPort(port)), 0, true);
- actorSystem.DispatchEvents();
-
- NActors::TActorId serverId = actorSystem.AllocateEdgeActor();
- actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true);
-
- NActors::TActorId clientId = actorSystem.AllocateEdgeActor();
- NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("http://127.0.0.1:" + ToString(port) + "/test");
- actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingRequest* request = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingRequest>(handle);
-
- UNIT_ASSERT_EQUAL(request->Request->URL, "/test");
-
- NHttp::THttpOutgoingResponsePtr httpResponse = request->Request->CreateResponseString("HTTP/1.1 200 Found\r\nConnection: Close\r\nTransfer-Encoding: chunked\r\n\r\n6\r\npassed\r\n0\r\n\r\n");
- actorSystem.Send(new NActors::IEventHandle(handle->Sender, serverId, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingResponse* response = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingResponse>(handle);
-
- UNIT_ASSERT_EQUAL(response->Response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Response->Body, "passed");
- }
-
- Y_UNIT_TEST(BasicRunning6) {
- NActors::TTestActorRuntimeBase actorSystem;
- TPortManager portManager;
- TIpPort port = portManager.GetTcpPort();
- TAutoPtr<NActors::IEventHandle> handle;
- actorSystem.Initialize();
- //actorSystem.SetLogPriority(NActorsServices::HTTP, NActors::NLog::PRI_DEBUG);
-
- NActors::IActor* proxy = NHttp::CreateHttpProxy();
- NActors::TActorId proxyId = actorSystem.Register(proxy);
- actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), new NHttp::TEvHttpProxy::TEvAddListeningPort(port)), 0, true);
- actorSystem.DispatchEvents();
-
- NActors::TActorId serverId = actorSystem.AllocateEdgeActor();
- actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true);
-
- NActors::TActorId clientId = actorSystem.AllocateEdgeActor();
- NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("http://[::1]:" + ToString(port) + "/test");
- actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingRequest* request = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingRequest>(handle);
-
- UNIT_ASSERT_EQUAL(request->Request->URL, "/test");
-
- NHttp::THttpOutgoingResponsePtr httpResponse = request->Request->CreateResponseString("HTTP/1.1 200 Found\r\nConnection: Close\r\nTransfer-Encoding: chunked\r\n\r\n6\r\npassed\r\n0\r\n\r\n");
- actorSystem.Send(new NActors::IEventHandle(handle->Sender, serverId, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingResponse* response = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingResponse>(handle);
-
- UNIT_ASSERT_EQUAL(response->Response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Response->Body, "passed");
- }
-
- Y_UNIT_TEST(TlsRunning) {
- NActors::TTestActorRuntimeBase actorSystem;
- TPortManager portManager;
- TIpPort port = portManager.GetTcpPort();
- TAutoPtr<NActors::IEventHandle> handle;
- actorSystem.Initialize();
-
- TString certificateContent = R"___(-----BEGIN PRIVATE KEY-----
-MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCzRZjodO7Aqe1w
-RyOj6kG6g2nn8ZGAxfao4mLT0jDTbVksrhV/h2s3uldLkFo5WrNQ8WZe+iIbXeFL
-s8tO6hslzreo9sih2IHoRcH5KnS/6YTqVhRTJb1jE2dM8NwYbwTi+T2Pe0FrBPjI
-kgVO50gAtYl9C+fc715uZiSKW+rRlP5OoFTwxrOjiU27RPZjFYyWK9wTI1Es9uRr
-lbZbLl5cY6dK2J1AViRraaYKCWO26VbOPWLsY4OD3e+ZXIc3OMCz6Yb0wmRPeJ60
-bbbkGfI8O27kDdv69MAWHIm0yYMzKEnom1dce7rNQNDEqJfocsYIsg+EvayT1yQ9
-KTBegw7LAgMBAAECggEBAKaOCrotqYQmXArsjRhFFDwMy+BKdzyEr93INrlFl0dX
-WHpCYobRcbOc1G3H94tB0UdqgAnNqtJyLlb+++ydZAuEOu4oGc8EL+10ofq0jzOd
-6Xct8kQt0/6wkFDTlii9PHUDy0X65ZRgUiNGRtg/2I2QG+SpowmI+trm2xwQueFs
-VaWrjc3cVvXx0b8Lu7hqZUv08kgC38stzuRk/n2T5VWSAr7Z4ZWQbO918Dv35HUw
-Wy/0jNUFP9CBCvFJ4l0OoH9nYhWFG+HXWzNdw6/Hca4jciRKo6esCiOZ9uWYv/ec
-/NvX9rgFg8G8/SrTisX10+Bbeq+R1RKwq/IG409TH4ECgYEA14L+3QsgNIUMeYAx
-jSCyk22R/tOHI1BM+GtKPUhnwHlAssrcPcxXMJovl6WL93VauYjym0wpCz9urSpA
-I2CqTsG8GYciA6Dr3mHgD6cK0jj9UPAU6EnZ5S0mjhPqKZqutu9QegzD2uESvuN8
-36xezwQthzAf0nI/P3sJGjVXjikCgYEA1POm5xcV6SmM6HnIdadEebhzZIJ9TXQz
-ry3Jj3a7CKyD5C7fAdkHUTCjgT/2ElxPi9ABkZnC+d/cW9GtJFa0II5qO/agm3KQ
-ZXYiutu9A7xACHYFXRiJEjVUdGG9dKMVOHUEa8IHEgrrcUVM/suy/GgutywIfaXs
-y58IFP24K9MCgYEAk6zjz7wL+XEiNy+sxLQfKf7vB9sSwxQHakK6wHuY/L8Zomp3
-uLEJHfjJm/SIkK0N2g0JkXkCtv5kbKyC/rsCeK0wo52BpVLjzaLr0k34kE0U6B1b
-dkEE2pGx1bG3x4KDLj+Wuct9ecK5Aa0IqIyI+vo16GkFpUM8K9e3SQo8UOECgYEA
-sCZYAkILYtJ293p9giz5rIISGasDAUXE1vxWBXEeJ3+kneTTnZCrx9Im/ewtnWR0
-fF90XL9HFDDD88POqAd8eo2zfKR2l/89SGBfPBg2EtfuU9FkgGyiPciVcqvC7q9U
-B15saMKX3KnhtdGwbfeLt9RqCCTJZT4SUSDcq5hwdvcCgYAxY4Be8mNipj8Cgg22
-mVWSolA0TEzbtUcNk6iGodpi+Z0LKpsPC0YRqPRyh1K+rIltG1BVdmUBHcMlOYxl
-lWWvbJH6PkJWy4n2MF7PO45kjN3pPZg4hgH63JjZeAineBwEArUGb9zHnvzcdRvF
-wuQ2pZHL/HJ0laUSieHDJ5917w==
------END PRIVATE KEY-----
-
-
------BEGIN CERTIFICATE-----
-MIIDjTCCAnWgAwIBAgIURt5IBx0J3xgEaQvmyrFH2A+NkpMwDQYJKoZIhvcNAQEL
-BQAwVjELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9z
-Y293MQ8wDQYDVQQKDAZZYW5kZXgxFDASBgNVBAMMC3Rlc3Qtc2VydmVyMB4XDTE5
-MDkyMDE3MTQ0MVoXDTQ3MDIwNDE3MTQ0MVowVjELMAkGA1UEBhMCUlUxDzANBgNV
-BAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MQ8wDQYDVQQKDAZZYW5kZXgxFDAS
-BgNVBAMMC3Rlc3Qtc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAs0WY6HTuwKntcEcjo+pBuoNp5/GRgMX2qOJi09Iw021ZLK4Vf4drN7pXS5Ba
-OVqzUPFmXvoiG13hS7PLTuobJc63qPbIodiB6EXB+Sp0v+mE6lYUUyW9YxNnTPDc
-GG8E4vk9j3tBawT4yJIFTudIALWJfQvn3O9ebmYkilvq0ZT+TqBU8Mazo4lNu0T2
-YxWMlivcEyNRLPbka5W2Wy5eXGOnStidQFYka2mmCgljtulWzj1i7GODg93vmVyH
-NzjAs+mG9MJkT3ietG225BnyPDtu5A3b+vTAFhyJtMmDMyhJ6JtXXHu6zUDQxKiX
-6HLGCLIPhL2sk9ckPSkwXoMOywIDAQABo1MwUTAdBgNVHQ4EFgQUDv/xuJ4CvCgG
-fPrZP3hRAt2+/LwwHwYDVR0jBBgwFoAUDv/xuJ4CvCgGfPrZP3hRAt2+/LwwDwYD
-VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAinKpMYaA2tjLpAnPVbjy
-/ZxSBhhB26RiQp3Re8XOKyhTWqgYE6kldYT0aXgK9x9mPC5obQannDDYxDc7lX+/
-qP/u1X81ZcDRo/f+qQ3iHfT6Ftt/4O3qLnt45MFM6Q7WabRm82x3KjZTqpF3QUdy
-tumWiuAP5DMd1IRDtnKjFHO721OsEsf6NLcqdX89bGeqXDvrkwg3/PNwTyW5E7cj
-feY8L2eWtg6AJUnIBu11wvfzkLiH3QKzHvO/SIZTGf5ihDsJ3aKEE9UNauTL3bVc
-CRA/5XcX13GJwHHj6LCoc3sL7mt8qV9HKY2AOZ88mpObzISZxgPpdKCfjsrdm63V
-6g==
------END CERTIFICATE-----)___";
-
- TTempFileHandle certificateFile;
-
- certificateFile.Write(certificateContent.data(), certificateContent.size());
-
- NActors::IActor* proxy = NHttp::CreateHttpProxy();
- NActors::TActorId proxyId = actorSystem.Register(proxy);
-
- THolder<NHttp::TEvHttpProxy::TEvAddListeningPort> add = MakeHolder<NHttp::TEvHttpProxy::TEvAddListeningPort>(port);
- ///////// https configuration
- add->Secure = true;
- add->CertificateFile = certificateFile.Name();
- add->PrivateKeyFile = certificateFile.Name();
- /////////
- actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), add.Release()), 0, true);
- actorSystem.DispatchEvents();
-
- NActors::TActorId serverId = actorSystem.AllocateEdgeActor();
- actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true);
-
- NActors::TActorId clientId = actorSystem.AllocateEdgeActor();
- NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("https://[::1]:" + ToString(port) + "/test");
- actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingRequest* request = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingRequest>(handle);
-
- UNIT_ASSERT_EQUAL(request->Request->URL, "/test");
-
- NHttp::THttpOutgoingResponsePtr httpResponse = request->Request->CreateResponseString("HTTP/1.1 200 Found\r\nConnection: Close\r\nTransfer-Encoding: chunked\r\n\r\n6\r\npassed\r\n0\r\n\r\n");
- actorSystem.Send(new NActors::IEventHandle(handle->Sender, serverId, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(httpResponse)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingResponse* response = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingResponse>(handle);
-
- UNIT_ASSERT_EQUAL(response->Response->Status, "200");
- UNIT_ASSERT_EQUAL(response->Response->Body, "passed");
- }
-
- /*Y_UNIT_TEST(AdvancedRunning) {
- THolder<NActors::TActorSystemSetup> setup = MakeHolder<NActors::TActorSystemSetup>();
- setup->NodeId = 1;
- setup->ExecutorsCount = 1;
- setup->Executors = new TAutoPtr<NActors::IExecutorPool>[1];
- setup->Executors[0] = new NActors::TBasicExecutorPool(0, 2, 10);
- setup->Scheduler = new NActors::TBasicSchedulerThread(NActors::TSchedulerConfig(512, 100));
- NActors::TActorSystem actorSystem(setup);
- actorSystem.Start();
- NHttp::THttpProxy* incomingProxy = new NHttp::THttpProxy();
- NActors::TActorId incomingProxyId = actorSystem.Register(incomingProxy);
- actorSystem.Send(incomingProxyId, new NHttp::TEvHttpProxy::TEvAddListeningPort(13337));
-
- NHttp::THttpProxy* outgoingProxy = new NHttp::THttpProxy();
- NActors::TActorId outgoingProxyId = actorSystem.Register(outgoingProxy);
-
- THolder<NHttp::THttpStaticStringRequest> httpRequest = MakeHolder<NHttp::THttpStaticStringRequest>("GET /test HTTP/1.1\r\n\r\n");
- actorSystem.Send(outgoingProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest("[::]:13337", std::move(httpRequest)));
-
- Sleep(TDuration::Minutes(60));
- }*/
-
- Y_UNIT_TEST(TooLongHeader) {
- NActors::TTestActorRuntimeBase actorSystem;
- actorSystem.SetUseRealInterconnect();
- TPortManager portManager;
- TIpPort port = portManager.GetTcpPort();
- TAutoPtr<NActors::IEventHandle> handle;
- actorSystem.Initialize();
-
- NActors::IActor* proxy = NHttp::CreateHttpProxy();
- NActors::TActorId proxyId = actorSystem.Register(proxy);
- actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), new NHttp::TEvHttpProxy::TEvAddListeningPort(port)), 0, true);
- actorSystem.DispatchEvents();
-
- NActors::TActorId serverId = actorSystem.AllocateEdgeActor();
- actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true);
-
- NActors::TActorId clientId = actorSystem.AllocateEdgeActor();
- NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("http://[::1]:" + ToString(port) + "/test");
- httpRequest->Set("Connection", "close");
- TString longHeader;
- longHeader.append(9000, 'X');
- httpRequest->Set(longHeader, "data");
- actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true);
-
- NHttp::TEvHttpProxy::TEvHttpIncomingResponse* response = actorSystem.GrabEdgeEvent<NHttp::TEvHttpProxy::TEvHttpIncomingResponse>(handle);
-
- UNIT_ASSERT_EQUAL(response->Response->Status, "400");
- UNIT_ASSERT_EQUAL(response->Response->Body, "Invalid http header");
- }
-}
diff --git a/library/cpp/actors/http/ut/CMakeLists.darwin-arm64.txt b/library/cpp/actors/http/ut/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index f9c9afac61..0000000000
--- a/library/cpp/actors/http/ut/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-http-ut)
-target_include_directories(library-cpp-actors-http-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http
-)
-target_link_libraries(library-cpp-actors-http-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-http
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-http-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-http-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-http-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-http-ut
- TEST_TARGET
- library-cpp-actors-http-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-http-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-http-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-http-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-http-ut)
diff --git a/library/cpp/actors/http/ut/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/http/ut/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 99677acae5..0000000000
--- a/library/cpp/actors/http/ut/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-http-ut)
-target_include_directories(library-cpp-actors-http-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http
-)
-target_link_libraries(library-cpp-actors-http-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-http
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-http-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-http-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-http-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-http-ut
- TEST_TARGET
- library-cpp-actors-http-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-http-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-http-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-http-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-http-ut)
diff --git a/library/cpp/actors/http/ut/CMakeLists.linux-aarch64.txt b/library/cpp/actors/http/ut/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 8818e4418f..0000000000
--- a/library/cpp/actors/http/ut/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-http-ut)
-target_include_directories(library-cpp-actors-http-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http
-)
-target_link_libraries(library-cpp-actors-http-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-http
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-http-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-http-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-http-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-http-ut
- TEST_TARGET
- library-cpp-actors-http-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-http-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-http-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-http-ut
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-http-ut)
diff --git a/library/cpp/actors/http/ut/CMakeLists.linux-x86_64.txt b/library/cpp/actors/http/ut/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 620f66ad00..0000000000
--- a/library/cpp/actors/http/ut/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-http-ut)
-target_include_directories(library-cpp-actors-http-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http
-)
-target_link_libraries(library-cpp-actors-http-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-http
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-http-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-http-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http/http_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-http-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-http-ut
- TEST_TARGET
- library-cpp-actors-http-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-http-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-http-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-http-ut
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-http-ut)
diff --git a/library/cpp/actors/http/ut/CMakeLists.txt b/library/cpp/actors/http/ut/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/http/ut/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/http/ut/CMakeLists.windows-x86_64.txt b/library/cpp/actors/http/ut/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 73603d626c..0000000000
--- a/library/cpp/actors/http/ut/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-http-ut)
-target_include_directories(library-cpp-actors-http-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/http
-)
-target_link_libraries(library-cpp-actors-http-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-http
- cpp-actors-testlib
-)
-set_property(
- TARGET
- library-cpp-actors-http-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-http-ut
- TEST_TARGET
- library-cpp-actors-http-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-http-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-http-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-http-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-http-ut)
diff --git a/library/cpp/actors/http/ut/ya.make b/library/cpp/actors/http/ut/ya.make
deleted file mode 100644
index 8404308053..0000000000
--- a/library/cpp/actors/http/ut/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-UNITTEST_FOR(library/cpp/actors/http)
-
-SIZE(SMALL)
-
-PEERDIR(
- library/cpp/actors/testlib
-)
-
-IF (NOT OS_WINDOWS)
-SRCS(
- http_ut.cpp
-)
-ELSE()
-ENDIF()
-
-END()
diff --git a/library/cpp/actors/http/ya.make b/library/cpp/actors/http/ya.make
deleted file mode 100644
index 9b66988ea9..0000000000
--- a/library/cpp/actors/http/ya.make
+++ /dev/null
@@ -1,36 +0,0 @@
-LIBRARY()
-
-SRCS(
- http_cache.cpp
- http_cache.h
- http_compress.cpp
- http_config.h
- http_proxy_acceptor.cpp
- http_proxy_incoming.cpp
- http_proxy_outgoing.cpp
- http_proxy_sock_impl.h
- http_proxy_sock64.h
- http_proxy_ssl.h
- http_proxy.cpp
- http_proxy.h
- http_static.cpp
- http_static.h
- http.cpp
- http.h
-)
-
-PEERDIR(
- contrib/libs/openssl
- contrib/libs/zlib
- library/cpp/actors/core
- library/cpp/actors/interconnect
- library/cpp/dns
- library/cpp/monlib/metrics
- library/cpp/string_utils/quote
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- ut
-)
diff --git a/library/cpp/actors/interconnect/CMakeLists.darwin-arm64.txt b/library/cpp/actors/interconnect/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 92e1fec219..0000000000
--- a/library/cpp/actors/interconnect/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(mock)
-add_subdirectory(ut)
-add_subdirectory(ut_fat)
-add_subdirectory(ut_huge_cluster)
-
-add_library(cpp-actors-interconnect)
-target_link_libraries(cpp-actors-interconnect PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-libc_compat
- contrib-libs-openssl
- contrib-libs-xxhash
- cpp-actors-core
- cpp-actors-dnscachelib
- cpp-actors-dnsresolver
- cpp-actors-helpers
- cpp-actors-prof
- cpp-actors-protos
- cpp-actors-util
- cpp-actors-wilson
- cpp-digest-crc32c
- library-cpp-json
- library-cpp-lwtrace
- cpp-monlib-dynamic_counters
- cpp-monlib-metrics
- service-pages-resources
- service-pages-tablesorter
- cpp-openssl-init
- library-cpp-packedtypes
-)
-target_sources(cpp-actors-interconnect PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_address.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_channel.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_counters.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_handshake.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_mon.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_nameserver_dynamic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_resolve.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_stream.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_session.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/load.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/packet.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit_select.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/types.cpp
-)
diff --git a/library/cpp/actors/interconnect/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/interconnect/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 92e1fec219..0000000000
--- a/library/cpp/actors/interconnect/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(mock)
-add_subdirectory(ut)
-add_subdirectory(ut_fat)
-add_subdirectory(ut_huge_cluster)
-
-add_library(cpp-actors-interconnect)
-target_link_libraries(cpp-actors-interconnect PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-libc_compat
- contrib-libs-openssl
- contrib-libs-xxhash
- cpp-actors-core
- cpp-actors-dnscachelib
- cpp-actors-dnsresolver
- cpp-actors-helpers
- cpp-actors-prof
- cpp-actors-protos
- cpp-actors-util
- cpp-actors-wilson
- cpp-digest-crc32c
- library-cpp-json
- library-cpp-lwtrace
- cpp-monlib-dynamic_counters
- cpp-monlib-metrics
- service-pages-resources
- service-pages-tablesorter
- cpp-openssl-init
- library-cpp-packedtypes
-)
-target_sources(cpp-actors-interconnect PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_address.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_channel.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_counters.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_handshake.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_mon.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_nameserver_dynamic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_resolve.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_stream.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_session.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/load.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/packet.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit_select.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/types.cpp
-)
diff --git a/library/cpp/actors/interconnect/CMakeLists.linux-aarch64.txt b/library/cpp/actors/interconnect/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 9fb3219fcf..0000000000
--- a/library/cpp/actors/interconnect/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(mock)
-add_subdirectory(ut)
-add_subdirectory(ut_fat)
-add_subdirectory(ut_huge_cluster)
-
-add_library(cpp-actors-interconnect)
-target_link_libraries(cpp-actors-interconnect PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-libc_compat
- contrib-libs-openssl
- contrib-libs-xxhash
- cpp-actors-core
- cpp-actors-dnscachelib
- cpp-actors-dnsresolver
- cpp-actors-helpers
- cpp-actors-prof
- cpp-actors-protos
- cpp-actors-util
- cpp-actors-wilson
- cpp-digest-crc32c
- library-cpp-json
- library-cpp-lwtrace
- cpp-monlib-dynamic_counters
- cpp-monlib-metrics
- service-pages-resources
- service-pages-tablesorter
- cpp-openssl-init
- library-cpp-packedtypes
-)
-target_sources(cpp-actors-interconnect PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_address.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_channel.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_counters.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_handshake.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_mon.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_nameserver_dynamic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_resolve.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_stream.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_session.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/load.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/packet.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit_select.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/types.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit_epoll.cpp
-)
diff --git a/library/cpp/actors/interconnect/CMakeLists.linux-x86_64.txt b/library/cpp/actors/interconnect/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 9fb3219fcf..0000000000
--- a/library/cpp/actors/interconnect/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(mock)
-add_subdirectory(ut)
-add_subdirectory(ut_fat)
-add_subdirectory(ut_huge_cluster)
-
-add_library(cpp-actors-interconnect)
-target_link_libraries(cpp-actors-interconnect PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-libc_compat
- contrib-libs-openssl
- contrib-libs-xxhash
- cpp-actors-core
- cpp-actors-dnscachelib
- cpp-actors-dnsresolver
- cpp-actors-helpers
- cpp-actors-prof
- cpp-actors-protos
- cpp-actors-util
- cpp-actors-wilson
- cpp-digest-crc32c
- library-cpp-json
- library-cpp-lwtrace
- cpp-monlib-dynamic_counters
- cpp-monlib-metrics
- service-pages-resources
- service-pages-tablesorter
- cpp-openssl-init
- library-cpp-packedtypes
-)
-target_sources(cpp-actors-interconnect PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_address.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_channel.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_counters.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_handshake.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_mon.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_nameserver_dynamic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_resolve.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_stream.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_session.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/load.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/packet.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit_select.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/types.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit_epoll.cpp
-)
diff --git a/library/cpp/actors/interconnect/CMakeLists.txt b/library/cpp/actors/interconnect/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/interconnect/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/interconnect/CMakeLists.windows-x86_64.txt b/library/cpp/actors/interconnect/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 92e1fec219..0000000000
--- a/library/cpp/actors/interconnect/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(mock)
-add_subdirectory(ut)
-add_subdirectory(ut_fat)
-add_subdirectory(ut_huge_cluster)
-
-add_library(cpp-actors-interconnect)
-target_link_libraries(cpp-actors-interconnect PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-libc_compat
- contrib-libs-openssl
- contrib-libs-xxhash
- cpp-actors-core
- cpp-actors-dnscachelib
- cpp-actors-dnsresolver
- cpp-actors-helpers
- cpp-actors-prof
- cpp-actors-protos
- cpp-actors-util
- cpp-actors-wilson
- cpp-digest-crc32c
- library-cpp-json
- library-cpp-lwtrace
- cpp-monlib-dynamic_counters
- cpp-monlib-metrics
- service-pages-resources
- service-pages-tablesorter
- cpp-openssl-init
- library-cpp-packedtypes
-)
-target_sources(cpp-actors-interconnect PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_address.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_channel.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_counters.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_handshake.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_mon.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_nameserver_dynamic.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_resolve.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_stream.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/interconnect_tcp_session.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/load.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/packet.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_actor.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/poller_tcp_unit_select.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/types.cpp
-)
diff --git a/library/cpp/actors/interconnect/channel_scheduler.h b/library/cpp/actors/interconnect/channel_scheduler.h
deleted file mode 100644
index b0eac9debc..0000000000
--- a/library/cpp/actors/interconnect/channel_scheduler.h
+++ /dev/null
@@ -1,116 +0,0 @@
-#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;
- 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,
- std::shared_ptr<IInterconnectMetrics> metrics, TEventHolderPool& pool, ui32 maxSerializedEventSize,
- 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_ABORT_UNLESS(!Heap.empty());
- return Heap.front().Channel;
- }
-
- void AddToHeap(TEventOutputChannel& channel, ui64 counter) {
- Y_DEBUG_ABORT_UNLESS(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,
- 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
- const ui64 min = Heap.front().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
deleted file mode 100644
index 47dabf5f16..0000000000
--- a/library/cpp/actors/interconnect/event_filter.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#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
diff --git a/library/cpp/actors/interconnect/event_holder_pool.h b/library/cpp/actors/interconnect/event_holder_pool.h
deleted file mode 100644
index 0afa1d7a7c..0000000000
--- a/library/cpp/actors/interconnect/event_holder_pool.h
+++ /dev/null
@@ -1,127 +0,0 @@
-#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;
-
- 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) {
- TAtomicBase res = Counter->fetch_sub(NumBytes) - NumBytes;
- Y_ABORT_UNLESS(res >= 0);
- }
- }
-
- bool GetInLineForDestruction(const TIntrusivePtr<TInterconnectProxyCommon>& common) {
- Y_ABORT_UNLESS(!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:
- TEvFreeItems* GetPendingEvent() {
- 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
deleted file mode 100644
index 465899c335..0000000000
--- a/library/cpp/actors/interconnect/events_local.h
+++ /dev/null
@@ -1,438 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/actors/core/event_local.h>
-#include <library/cpp/actors/protos/interconnect.pb.h>
-#include <util/generic/deque.h>
-#include <util/network/address.h>
-
-#include "interconnect_stream.h"
-#include "types.h"
-
-namespace NActors {
- enum class ENetwork : ui32 {
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // local messages
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- Start = EventSpaceBegin(TEvents::ES_INTERCONNECT_TCP),
-
- SocketReadyRead = Start,
- SocketReadyWrite,
- SocketError,
- Connect,
- Disconnect,
- IncomingConnection,
- HandshakeAsk,
- HandshakeAck,
- HandshakeNak,
- HandshakeDone,
- HandshakeFail,
- Kick,
- Flush,
- NodeInfo,
- BunchOfEventsToDestroy,
- HandshakeRequest,
- HandshakeReplyOK,
- HandshakeReplyError,
- ResolveAddress,
- AddressInfo,
- ResolveError,
- HTTPStreamStatus,
- HTTPSendContent,
- ConnectProtocolWakeup,
- HTTPProtocolRetry,
- EvPollerRegister,
- EvPollerRegisterResult,
- EvPollerReady,
- EvUpdateFromInputSession,
- EvConfirmUpdate,
- EvSessionBufferSizeRequest,
- EvSessionBufferSizeResponse,
- EvProcessPingRequest,
- EvGetSecureSocket,
- EvSecureSocket,
- HandshakeBrokerTake,
- HandshakeBrokerFree,
- HandshakeBrokerPermit,
-
- // external data channel messages
- EvSubscribeForConnection,
- EvReportConnection,
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // nonlocal messages; their indices must be preserved in order to work properly while doing rolling update
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- // interconnect load test message
- EvLoadMessage = Start + 256,
- };
-
- struct TEvSocketReadyRead: public TEventLocal<TEvSocketReadyRead, ui32(ENetwork::SocketReadyRead)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvSocketReadyRead, "Network: TEvSocketReadyRead")
- };
-
- struct TEvSocketReadyWrite: public TEventLocal<TEvSocketReadyWrite, ui32(ENetwork::SocketReadyWrite)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvSocketReadyWrite, "Network: TEvSocketReadyWrite")
- };
-
- struct TEvSocketError: public TEventLocal<TEvSocketError, ui32(ENetwork::SocketError)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvSocketError, ::strerror(Error))
- TString GetReason() const {
- return ::strerror(Error);
- }
- const int Error;
- TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
-
- TEvSocketError(int error, TIntrusivePtr<NInterconnect::TStreamSocket> sock)
- : Error(error)
- , Socket(std::move(sock))
- {
- }
- };
-
- struct TEvSocketConnect: public TEventLocal<TEvSocketConnect, ui32(ENetwork::Connect)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvSocketConnect, "Network: TEvSocketConnect")
- };
-
- struct TEvSocketDisconnect: public TEventLocal<TEvSocketDisconnect, ui32(ENetwork::Disconnect)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvSocketDisconnect, "Network: TEvSocketDisconnect")
- TDisconnectReason Reason;
-
- TEvSocketDisconnect(TDisconnectReason reason)
- : Reason(std::move(reason))
- {
- }
- };
-
- struct TEvHandshakeBrokerTake: TEventLocal<TEvHandshakeBrokerTake, ui32(ENetwork::HandshakeBrokerTake)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeBrokerTake, "Network: TEvHandshakeBrokerTake")
- };
-
- struct TEvHandshakeBrokerFree: TEventLocal<TEvHandshakeBrokerFree, ui32(ENetwork::HandshakeBrokerFree)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeBrokerFree, "Network: TEvHandshakeBrokerFree")
- };
-
- struct TEvHandshakeBrokerPermit: TEventLocal<TEvHandshakeBrokerPermit, ui32(ENetwork::HandshakeBrokerPermit)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeBrokerPermit, "Network: TEvHandshakeBrokerPermit")
- };
-
- struct TEvHandshakeAsk: public TEventLocal<TEvHandshakeAsk, ui32(ENetwork::HandshakeAsk)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeAsk, "Network: TEvHandshakeAsk")
- TEvHandshakeAsk(const TActorId& self,
- const TActorId& peer,
- ui64 counter)
- : Self(self)
- , Peer(peer)
- , Counter(counter)
- {
- }
- const TActorId Self;
- const TActorId Peer;
- const ui64 Counter;
- };
-
- struct TEvHandshakeAck: public TEventLocal<TEvHandshakeAck, ui32(ENetwork::HandshakeAck)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeAck, "Network: TEvHandshakeAck")
-
- TEvHandshakeAck(const TActorId& self, ui64 nextPacket, TSessionParams params)
- : Self(self)
- , NextPacket(nextPacket)
- , 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")
- };
-
- struct TEvHandshakeRequest
- : public TEventLocal<TEvHandshakeRequest,
- ui32(ENetwork::HandshakeRequest)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeRequest,
- "Network: TEvHandshakeRequest")
-
- NActorsInterconnect::THandshakeRequest Record;
- };
-
- struct TEvHandshakeReplyOK
- : public TEventLocal<TEvHandshakeReplyOK,
- ui32(ENetwork::HandshakeReplyOK)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeReplyOK,
- "Network: TEvHandshakeReplyOK")
-
- NActorsInterconnect::THandshakeReply Record;
- };
-
- struct TEvHandshakeReplyError
- : public TEventLocal<TEvHandshakeReplyError,
- ui32(ENetwork::HandshakeReplyError)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeReplyError,
- "Network: TEvHandshakeReplyError")
-
- TEvHandshakeReplyError(TString error) {
- Record.SetErrorExplaination(error);
- }
-
- NActorsInterconnect::THandshakeReply Record;
- };
-
- struct TEvIncomingConnection: public TEventLocal<TEvIncomingConnection, ui32(ENetwork::IncomingConnection)> {
- 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))
- {}
- };
-
- struct TEvHandshakeDone: public TEventLocal<TEvHandshakeDone, ui32(ENetwork::HandshakeDone)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeDone, "Network: TEvHandshakeDone")
-
- TEvHandshakeDone(
- TIntrusivePtr<NInterconnect::TStreamSocket> socket,
- const TActorId& peer,
- const TActorId& self,
- ui64 nextPacket,
- TAutoPtr<TProgramInfo>&& programInfo,
- TSessionParams params,
- TIntrusivePtr<NInterconnect::TStreamSocket> xdcSocket)
- : Socket(std::move(socket))
- , Peer(peer)
- , Self(self)
- , NextPacket(nextPacket)
- , ProgramInfo(std::move(programInfo))
- , Params(std::move(params))
- , XdcSocket(std::move(xdcSocket))
- {
- }
-
- TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
- const TActorId Peer;
- const TActorId Self;
- const ui64 NextPacket;
- TAutoPtr<TProgramInfo> ProgramInfo;
- const TSessionParams Params;
- TIntrusivePtr<NInterconnect::TStreamSocket> XdcSocket;
- };
-
- struct TEvHandshakeFail: public TEventLocal<TEvHandshakeFail, ui32(ENetwork::HandshakeFail)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeFail, "Network: TEvHandshakeFail")
-
- enum EnumHandshakeFail {
- HANDSHAKE_FAIL_TRANSIENT,
- HANDSHAKE_FAIL_PERMANENT,
- HANDSHAKE_FAIL_SESSION_MISMATCH,
- };
-
- TEvHandshakeFail(EnumHandshakeFail temporary, TString explanation)
- : Temporary(temporary)
- , Explanation(std::move(explanation))
- {
- }
-
- const EnumHandshakeFail Temporary;
- const TString Explanation;
- };
-
- struct TEvKick: public TEventLocal<TEvKick, ui32(ENetwork::Kick)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvKick, "Network: TEvKick")
- };
-
- struct TEvFlush: public TEventLocal<TEvFlush, ui32(ENetwork::Flush)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvFlush, "Network: TEvFlush")
- };
-
- struct TEvLocalNodeInfo
- : public TEventLocal<TEvLocalNodeInfo, ui32(ENetwork::NodeInfo)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvLocalNodeInfo, "Network: TEvLocalNodeInfo")
-
- ui32 NodeId;
- std::vector<NInterconnect::TAddress> Addresses;
- };
-
- struct TEvBunchOfEventsToDestroy : TEventLocal<TEvBunchOfEventsToDestroy, ui32(ENetwork::BunchOfEventsToDestroy)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvBunchOfEventsToDestroy,
- "Network: TEvBunchOfEventsToDestroy")
-
- TEvBunchOfEventsToDestroy(TDeque<TAutoPtr<IEventBase>> events)
- : Events(std::move(events))
- {
- }
-
- TDeque<TAutoPtr<IEventBase>> Events;
- };
-
- struct TEvResolveAddress
- : public TEventLocal<TEvResolveAddress, ui32(ENetwork::ResolveAddress)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvResolveAddress, "Network: TEvResolveAddress")
-
- TString Address;
- ui16 Port;
- };
-
- struct TEvAddressInfo
- : public TEventLocal<TEvAddressInfo, ui32(ENetwork::AddressInfo)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvAddressInfo, "Network: TEvAddressInfo")
-
- NAddr::IRemoteAddrPtr Address;
- };
-
- struct TEvResolveError
- : public TEventLocal<TEvResolveError, ui32(ENetwork::ResolveError)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvResolveError, "Network: TEvResolveError")
-
- TString Explain;
- TString Host;
- };
-
- struct TEvHTTPStreamStatus
- : public TEventLocal<TEvHTTPStreamStatus, ui32(ENetwork::HTTPStreamStatus)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHTTPStreamStatus,
- "Network: TEvHTTPStreamStatus")
- enum EStatus {
- READY,
- COMPLETE,
- ERROR,
- };
-
- EStatus Status;
- TString Error;
- TString HttpHeaders;
- };
-
- struct TEvHTTPSendContent
- : public TEventLocal<TEvHTTPSendContent, ui32(ENetwork::HTTPSendContent)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHTTPSendContent, "Network: TEvHTTPSendContent")
-
- const char* Data;
- size_t Len;
- bool Last;
- };
-
- struct TEvConnectWakeup
- : public TEventLocal<TEvConnectWakeup,
- ui32(ENetwork::ConnectProtocolWakeup)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvConnectWakeup, "Protocols: TEvConnectWakeup")
- };
-
- struct TEvHTTPProtocolRetry
- : public TEventLocal<TEvHTTPProtocolRetry,
- ui32(ENetwork::HTTPProtocolRetry)> {
- DEFINE_SIMPLE_LOCAL_EVENT(TEvHTTPProtocolRetry,
- "Protocols: TEvHTTPProtocolRetry")
- };
-
- struct TEvLoadMessage
- : TEventPB<TEvLoadMessage, NActorsInterconnect::TEvLoadMessage, static_cast<ui32>(ENetwork::EvLoadMessage)> {
- TEvLoadMessage() = default;
-
- template <typename TContainer>
- TEvLoadMessage(const TContainer& route, const TString& id, const TString* payload) {
- for (const TActorId& actorId : route) {
- auto* hop = Record.AddHops();
- if (actorId) {
- ActorIdToProto(actorId, hop->MutableNextHop());
- }
- }
- Record.SetId(id);
- if (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));
- }
- };
-
- 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)
- : ConfirmedByInput(confirmedByInput)
- , NumDataBytes(numDataBytes)
- , Ping(ping)
- {
- }
- };
-
- 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");
- };
-
- struct TEvSessionBufferSizeResponse : TEventLocal<TEvSessionBufferSizeResponse, static_cast<ui32>(ENetwork::EvSessionBufferSizeResponse)> {
- TEvSessionBufferSizeResponse(const TActorId& sessionId, ui64 outputBufferSize)
- : SessionID(sessionId)
- , BufferSize(outputBufferSize)
- {
- }
-
- TActorId SessionID;
- 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 TEvSubscribeForConnection : TEventLocal<TEvSubscribeForConnection, (ui32)ENetwork::EvSubscribeForConnection> {
- TString HandshakeId;
- bool Subscribe;
-
- TEvSubscribeForConnection(TString handshakeId, bool subscribe)
- : HandshakeId(std::move(handshakeId))
- , Subscribe(subscribe)
- {}
- };
-
- struct TEvReportConnection : TEventLocal<TEvReportConnection, (ui32)ENetwork::EvReportConnection> {
- TString HandshakeId;
- TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
-
- TEvReportConnection(TString handshakeId, TIntrusivePtr<NInterconnect::TStreamSocket> socket)
- : HandshakeId(std::move(handshakeId))
- , Socket(std::move(socket))
- {}
- };
-}
diff --git a/library/cpp/actors/interconnect/handshake_broker.h b/library/cpp/actors/interconnect/handshake_broker.h
deleted file mode 100644
index c850320bd2..0000000000
--- a/library/cpp/actors/interconnect/handshake_broker.h
+++ /dev/null
@@ -1,156 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/interconnect/events_local.h>
-
-#include <deque>
-
-namespace NActors {
- class TBrokerLeaseHolder {
- public:
- TBrokerLeaseHolder(TActorId waiterId, TActorId brokerId)
- : WaiterId(waiterId)
- , BrokerId(brokerId) {
- if (TActivationContext::Send(new IEventHandle(BrokerId, WaiterId, new TEvHandshakeBrokerTake()))) {
- LeaseRequested = true;
- }
- }
-
- ~TBrokerLeaseHolder() {
- if (LeaseRequested) {
- TActivationContext::Send(new IEventHandle(BrokerId, WaiterId, new TEvHandshakeBrokerFree()));
- }
- }
-
- bool IsLeaseRequested() {
- return LeaseRequested;
- }
-
- void ForgetLease() {
- // only call when TDtorException was caught
- LeaseRequested = false;
- }
-
- private:
- TActorId WaiterId;
- TActorId BrokerId;
- bool LeaseRequested = false;
- };
-
- class THandshakeBroker : public TActor<THandshakeBroker> {
- private:
- enum class ESelectionStrategy {
- FIFO = 0,
- LIFO,
- Random,
- };
-
- private:
- void PermitNext() {
- if (Capacity == 0 && !Waiters.empty()) {
- TActorId waiter;
-
- switch (SelectionStrategy) {
- case ESelectionStrategy::FIFO:
- waiter = Waiters.front();
- Waiters.pop_front();
- SelectionStrategy = ESelectionStrategy::LIFO;
- break;
-
- case ESelectionStrategy::LIFO:
- waiter = Waiters.back();
- Waiters.pop_back();
- SelectionStrategy = ESelectionStrategy::Random;
- break;
-
- case ESelectionStrategy::Random: {
- const auto it = WaiterLookup.begin();
- waiter = it->first;
- Waiters.erase(it->second);
- SelectionStrategy = ESelectionStrategy::FIFO;
- break;
- }
-
- default:
- Y_ABORT("Unimplimented selection strategy");
- }
-
- const size_t n = WaiterLookup.erase(waiter);
- Y_ABORT_UNLESS(n == 1);
-
- Send(waiter, new TEvHandshakeBrokerPermit());
- PermittedLeases.insert(waiter);
- } else {
- Capacity += 1;
- }
- }
-
- private:
- using TWaiters = std::list<TActorId>;
- TWaiters Waiters;
- std::unordered_map<TActorId, TWaiters::iterator> WaiterLookup;
- std::unordered_set<TActorId> PermittedLeases;
-
- ESelectionStrategy SelectionStrategy = ESelectionStrategy::FIFO;
-
- ui32 Capacity;
-
- void Handle(TEvHandshakeBrokerTake::TPtr &ev) {
- const TActorId sender = ev->Sender;
- if (Capacity > 0) {
- Capacity -= 1;
- PermittedLeases.insert(sender);
- Send(sender, new TEvHandshakeBrokerPermit());
- } else {
- const auto [it, inserted] = WaiterLookup.try_emplace(sender,
- Waiters.insert(Waiters.end(), sender));
- Y_ABORT_UNLESS(inserted);
- }
- }
-
- void Handle(TEvHandshakeBrokerFree::TPtr& ev) {
- const TActorId sender = ev->Sender;
- if (!PermittedLeases.erase(sender)) {
- // Lease was not permitted yet, remove sender from Waiters queue
- const auto it = WaiterLookup.find(sender);
- Y_ABORT_UNLESS(it != WaiterLookup.end());
- Waiters.erase(it->second);
- WaiterLookup.erase(it);
- }
- PermitNext();
- }
-
- public:
- THandshakeBroker(ui32 inflightLimit)
- : TActor(&TThis::StateFunc)
- , Capacity(inflightLimit)
- {
- }
-
- static constexpr char ActorName[] = "HANDSHAKE_BROKER_ACTOR";
-
- STFUNC(StateFunc) {
- switch (ev->GetTypeRewrite()) {
- hFunc(TEvHandshakeBrokerTake, Handle);
- hFunc(TEvHandshakeBrokerFree, Handle);
-
- default:
- Y_ABORT("unexpected event 0x%08" PRIx32, ev->GetTypeRewrite());
- }
- }
-
- void Bootstrap() {
- Become(&TThis::StateFunc);
- }
- };
-
- inline IActor* CreateHandshakeBroker(ui32 maxCapacity) {
- return new THandshakeBroker(maxCapacity);
- }
-
- inline TActorId MakeHandshakeBrokerOutId() {
- char x[12] = {'I', 'C', 'H', 's', 'h', 'k', 'B', 'r', 'k', 'O', 'u', 't'};
- return TActorId(0, TStringBuf(std::begin(x), std::end(x)));
- }
-}
diff --git a/library/cpp/actors/interconnect/interconnect.h b/library/cpp/actors/interconnect/interconnect.h
deleted file mode 100644
index 38d8cd4781..0000000000
--- a/library/cpp/actors/interconnect/interconnect.h
+++ /dev/null
@@ -1,189 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actorsystem.h>
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/interconnect.h>
-#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;
- TString& first;
- ui16& second;
-
- TNodeInfo()
- : first(Address)
- , second(Port)
- {
- }
-
- TNodeInfo(const TNodeInfo&) = default;
-
- // for testing purposes only
- TNodeInfo(const TString& address, const TString& host, ui16 port)
- : TNodeInfo()
- {
- Address = address;
- Host = host;
- ResolveHost = host;
- Port = port;
- }
-
- TNodeInfo(const TString& address,
- const TString& host,
- const TString& resolveHost,
- ui16 port,
- const TNodeLocation& location)
- : TNodeInfo()
- {
- Address = address;
- Host = host;
- ResolveHost = resolveHost;
- Port = port;
- Location = location;
- }
-
- // for testing purposes only
- TNodeInfo& operator=(const std::pair<TString, ui32>& pr) {
- Address = pr.first;
- Host = pr.first;
- ResolveHost = pr.first;
- Port = pr.second;
- return *this;
- }
-
- TNodeInfo& operator=(const TNodeInfo& ni) {
- Address = ni.Address;
- Host = ni.Host;
- ResolveHost = ni.ResolveHost;
- Port = ni.Port;
- Location = ni.Location;
- return *this;
- }
-
- friend bool operator ==(const TNodeInfo& x, const TNodeInfo& y) {
- return x.Address == y.Address && x.Host == y.Host && x.ResolveHost == y.ResolveHost && x.Port == y.Port
- && x.Location == y.Location;
- }
-
- friend bool operator !=(const TNodeInfo& x, const TNodeInfo& y) {
- return !(x == y);
- }
- };
-
- TMap<ui32, TNodeInfo> StaticNodeTable;
-
- bool IsEntriesUnique() const;
- };
-
- struct TNodeRegistrarSetup {
- TActorId ServiceID;
-
- TIntrusivePtr<TInterconnectGlobalState> GlobalState;
- };
-
- TActorId GetNameserviceActorId();
-
- /**
- * Const table-lookup based name service
- */
-
- 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).
- * Handles TEvNodesInfo to change list of known nodes.
- *
- * If PendingPeriod is not zero, wait for unknown nodeId
- */
-
- IActor* CreateDynamicNameserver(
- const TIntrusivePtr<TTableNameserverSetup>& setup,
- const TDuration& pendingPeriod = TDuration::Zero(),
- ui32 poolId = 0);
-
- /**
- * Creates an actor that resolves host/port and replies with either:
- *
- * - TEvLocalNodeInfo on success
- * - TEvResolveError on errors
- *
- * Optional defaultAddress may be used as fallback.
- */
- IActor* CreateResolveActor(
- const TString& host, ui16 port, ui32 nodeId, const TString& defaultAddress,
- const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline);
-
- inline IActor* CreateResolveActor(
- ui32 nodeId, const TTableNameserverSetup::TNodeInfo& nodeInfo,
- const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline)
- {
- return CreateResolveActor(nodeInfo.ResolveHost, nodeInfo.Port, nodeId, nodeInfo.Address,
- replyTo, replyFrom, deadline);
- }
-
- /**
- * Creates an actor that resolves host/port and replies with either:
- *
- * - TEvAddressInfo on success
- * - TEvResolveError on errors
- */
- IActor* CreateResolveActor(
- 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
deleted file mode 100644
index 124cd61325..0000000000
--- a/library/cpp/actors/interconnect/interconnect_address.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-#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));
- }
-
- TAddress::TAddress(NAddr::IRemoteAddr& addr) {
- socklen_t len = addr.Len();
- Y_ABORT_UNLESS(len <= sizeof(Addr));
- memcpy(&Addr.Generic, addr.Addr(), len);
- }
-
- int TAddress::GetFamily() const {
- return Addr.Generic.sa_family;
- }
-
- socklen_t TAddress::Size() const {
- switch (Addr.Generic.sa_family) {
- case AF_INET6:
- return sizeof(sockaddr_in6);
- case AF_INET:
- return sizeof(sockaddr_in);
- default:
- return 0;
- }
- }
-
- sockaddr* TAddress::SockAddr() {
- return &Addr.Generic;
- }
-
- const sockaddr* TAddress::SockAddr() const {
- return &Addr.Generic;
- }
-
- ui16 TAddress::GetPort() const {
- switch (Addr.Generic.sa_family) {
- case AF_INET6:
- return ntohs(Addr.Ipv6.sin6_port);
- case AF_INET:
- 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) > 0) {
- Addr.Ipv6.sin6_port = htons(port);
- } else if (inet_pton(Addr.Ipv4.sin_family = AF_INET, addr, &Addr.Ipv4.sin_addr) > 0) {
- Addr.Ipv4.sin_port = htons(port);
- }
- }
-
- TAddress::TAddress(const TString& addr, ui16 port)
- : TAddress(addr.data(), port)
- {}
-
- TAddress::TAddress(in_addr addr, ui16 port) {
- Addr.Ipv4.sin_family = AF_INET;
- Addr.Ipv4.sin_port = htons(port);
- Addr.Ipv4.sin_addr = addr;
- }
-
- TAddress::TAddress(in6_addr addr, ui16 port) {
- Addr.Ipv6.sin6_family = AF_INET6;
- Addr.Ipv6.sin6_port = htons(port);
- Addr.Ipv6.sin6_addr = addr;
- }
-
- 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;
-
- case AF_INET:
- 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();
- }
-}
diff --git a/library/cpp/actors/interconnect/interconnect_address.h b/library/cpp/actors/interconnect/interconnect_address.h
deleted file mode 100644
index b19d751806..0000000000
--- a/library/cpp/actors/interconnect/interconnect_address.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#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;
-
- public:
- TAddress();
- TAddress(const char* addr, ui16 port);
- TAddress(const TString& addr, ui16 port);
- TAddress(in_addr addr, ui16 port);
- TAddress(in6_addr addr, ui16 port);
- TAddress(NAddr::IRemoteAddr& addr);
- int GetFamily() const;
- socklen_t Size() const;
- ::sockaddr* SockAddr();
- const ::sockaddr* SockAddr() const;
- ui16 GetPort() const;
- TString GetAddress() const;
- TString ToString() const;
-
- static TAddress AnyIPv4(ui16 port) {
- TAddress res;
- res.Addr.Ipv4.sin_family = AF_INET;
- res.Addr.Ipv4.sin_port = htons(port);
- res.Addr.Ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
- return res;
- }
-
- static TAddress AnyIPv6(ui16 port) {
- TAddress res;
- res.Addr.Ipv6.sin6_family = AF_INET6;
- res.Addr.Ipv6.sin6_port = htons(port);
- res.Addr.Ipv6.sin6_addr = in6addr_any;
- return res;
- }
- };
-}
diff --git a/library/cpp/actors/interconnect/interconnect_channel.cpp b/library/cpp/actors/interconnect/interconnect_channel.cpp
deleted file mode 100644
index 71f4d6e5c3..0000000000
--- a/library/cpp/actors/interconnect/interconnect_channel.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-#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>
-#include <library/cpp/actors/core/probes.h>
-#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 {
- bool TEventOutputChannel::FeedDescriptor(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed) {
- const size_t amount = sizeof(TChannelPart) + sizeof(TEventDescr2);
- if (task.GetInternalFreeAmount() < amount) {
- return false;
- }
-
- auto traceId = event.Span.GetTraceId();
- event.Span.EndOk();
-
- Y_ABORT_UNLESS(SerializationInfo);
- const ui32 flags = (event.Descr.Flags & ~IEventHandle::FlagForwardOnNondelivery) |
- (SerializationInfo->IsExtendedFormat ? IEventHandle::FlagExtendedFormat : 0);
-
- // prepare descriptor record
- TEventDescr2 descr{
- event.Descr.Type,
- flags,
- event.Descr.Recipient,
- event.Descr.Sender,
- event.Descr.Cookie,
- {},
- event.Descr.Checksum,
-#if IC_FORCE_HARDENED_PACKET_CHECKS
- event.EventSerializedSize
-#endif
- };
- traceId.Serialize(&descr.TraceId);
-
- // and channel header before the descriptor
- TChannelPart part{
- .ChannelFlags = static_cast<ui16>(ChannelId | TChannelPart::LastPartFlag),
- .Size = sizeof(descr)
- };
-
- // append them to the packet
- task.Write<false>(&part, sizeof(part));
- task.Write<false>(&descr, sizeof(descr));
-
- *weightConsumed += amount;
- OutputQueueSize -= sizeof(TEventDescr2);
- Metrics->UpdateOutputChannelEvents(ChannelId);
-
- 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++);
- }
- }
-
- bool TEventOutputChannel::FeedBuf(TTcpPacketOutTask& task, ui64 serial, ui64 *weightConsumed) {
- for (;;) {
- Y_ABORT_UNLESS(!Queue.empty());
- TEventHolder& event = Queue.front();
-
- switch (State) {
- case EState::INITIAL:
- event.InitChecksum();
- if (event.Buffer) {
- State = EState::BODY;
- Iter = event.Buffer->GetBeginIter();
- SerializationInfo = &event.Buffer->GetSerializationInfo();
- SectionIndex = 0;
- PartLenRemain = 0;
- } else if (event.Event) {
- State = EState::BODY;
- IEventBase *base = event.Event.Get();
- if (event.EventSerializedSize) {
- Chunker.SetSerializingEvent(base);
- }
- SerializationInfoContainer = base->CreateSerializationInfo();
- SerializationInfo = &SerializationInfoContainer;
- SectionIndex = 0;
- PartLenRemain = 0;
- } else { // event without buffer and IEventBase instance
- State = EState::DESCRIPTOR;
- SerializationInfoContainer = {};
- SerializationInfo = &SerializationInfoContainer;
- }
- if (!event.EventSerializedSize) {
- State = EState::DESCRIPTOR;
- } else if (Params.UseExternalDataChannel && !SerializationInfo->Sections.empty()) {
- State = EState::SECTIONS;
- SectionIndex = 0;
- }
- break;
-
- case EState::BODY:
- if (FeedPayload(task, event, weightConsumed)) {
- State = EState::DESCRIPTOR;
- } else {
- return false;
- }
- 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
- SerializationInfoContainer = {};
- SerializationInfo = nullptr;
- State = EState::INITIAL;
- return true; // we have processed whole event, signal to the caller
-
- case EState::SECTIONS: {
- if (SectionIndex == 0) {
- size_t totalSectionSize = 0;
- for (const auto& section : SerializationInfo->Sections) {
- totalSectionSize += section.Size;
- }
- Y_ABORT_UNLESS(totalSectionSize == event.EventSerializedSize);
- }
-
- while (SectionIndex != SerializationInfo->Sections.size()) {
- char sectionInfo[1 + NInterconnect::NDetail::MaxNumberBytes * 4];
- char *p = sectionInfo;
-
- const auto& section = SerializationInfo->Sections[SectionIndex];
- char& type = *p++;
- type = static_cast<ui8>(EXdcCommand::DECLARE_SECTION);
- p += NInterconnect::NDetail::SerializeNumber(section.Headroom, p);
- p += NInterconnect::NDetail::SerializeNumber(section.Size, p);
- p += NInterconnect::NDetail::SerializeNumber(section.Tailroom, p);
- p += NInterconnect::NDetail::SerializeNumber(section.Alignment, p);
- if (section.IsInline && Params.UseXdcShuffle) {
- type = static_cast<ui8>(EXdcCommand::DECLARE_SECTION_INLINE);
- }
- Y_ABORT_UNLESS(p <= std::end(sectionInfo));
-
- const size_t declareLen = p - sectionInfo;
- if (sizeof(TChannelPart) + XdcData.size() + declareLen <= task.GetInternalFreeAmount() &&
- XdcData.size() + declareLen <= Max<ui16>()) {
- XdcData.insert(XdcData.end(), sectionInfo, p);
- ++SectionIndex;
- } else {
- break;
- }
- }
-
- if (XdcData.empty()) {
- return false;
- }
-
- TChannelPart part{
- .ChannelFlags = static_cast<ui16>(ChannelId | TChannelPart::XdcFlag),
- .Size = static_cast<ui16>(XdcData.size())
- };
- task.Write<false>(&part, sizeof(part));
- task.Write<false>(XdcData.data(), XdcData.size());
- XdcData.clear();
-
- if (SectionIndex == SerializationInfo->Sections.size()) {
- State = EState::BODY;
- SectionIndex = 0;
- PartLenRemain = 0;
- }
-
- break;
- }
- }
- }
- }
-
- template<bool External>
- bool TEventOutputChannel::SerializeEvent(TTcpPacketOutTask& task, TEventHolder& event, size_t *bytesSerialized) {
- auto addChunk = [&](const void *data, size_t len, bool allowCopy) {
- event.UpdateChecksum(data, len);
- if (allowCopy && (reinterpret_cast<uintptr_t>(data) & 63) + len <= 64) {
- task.Write<External>(data, len);
- } else {
- task.Append<External>(data, len);
- }
- *bytesSerialized += len;
- Y_DEBUG_ABORT_UNLESS(len <= PartLenRemain);
- PartLenRemain -= len;
-
- event.EventActuallySerialized += len;
- if (event.EventActuallySerialized > MaxSerializedEventSize) {
- throw TExSerializedEventTooLarge(event.Descr.Type);
- }
- };
-
- bool complete = false;
- if (event.Event) {
- while (!complete) {
- TMutableContiguousSpan out = task.AcquireSpanForWriting<External>().SubSpan(0, PartLenRemain);
- if (!out.size()) {
- break;
- }
- for (const auto& [buffer, size] : Chunker.FeedBuf(out.data(), out.size())) {
- addChunk(buffer, size, false);
- }
- complete = Chunker.IsComplete();
- if (complete) {
- Y_ABORT_UNLESS(Chunker.IsSuccessfull());
- }
- }
- } else if (event.Buffer) {
- while (const size_t numb = Min<size_t>(External ? task.GetExternalFreeAmount() : task.GetInternalFreeAmount(),
- Iter.ContiguousSize(), PartLenRemain)) {
- const char *obuf = Iter.ContiguousData();
- addChunk(obuf, numb, true);
- Iter += numb;
- }
- complete = !Iter.Valid();
- } else {
- Y_ABORT();
- }
- Y_ABORT_UNLESS(!complete || event.EventActuallySerialized == event.EventSerializedSize,
- "EventActuallySerialized# %" PRIu32 " EventSerializedSize# %" PRIu32 " Type# 0x%08" PRIx32,
- event.EventActuallySerialized, event.EventSerializedSize, event.Descr.Type);
-
- return complete;
- }
-
- bool TEventOutputChannel::FeedPayload(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed) {
- for (;;) {
- // calculate inline or external part size (it may cover a few sections, not just single one)
- while (!PartLenRemain) {
- const auto& sections = SerializationInfo->Sections;
- if (!Params.UseExternalDataChannel || sections.empty()) {
- // all data goes inline
- IsPartInline = true;
- PartLenRemain = Max<size_t>();
- } else if (!Params.UseXdcShuffle) {
- // when UseXdcShuffle feature is not supported by the remote side, we transfer whole event over XDC
- IsPartInline = false;
- PartLenRemain = Max<size_t>();
- } else {
- Y_ABORT_UNLESS(SectionIndex < sections.size());
- IsPartInline = sections[SectionIndex].IsInline;
- while (SectionIndex < sections.size() && IsPartInline == sections[SectionIndex].IsInline) {
- PartLenRemain += sections[SectionIndex].Size;
- ++SectionIndex;
- }
- }
- }
-
- // serialize bytes
- const auto complete = IsPartInline
- ? FeedInlinePayload(task, event, weightConsumed)
- : FeedExternalPayload(task, event, weightConsumed);
- if (!complete) { // no space to serialize
- return false;
- } else if (*complete) { // event serialized
- return true;
- }
- }
- }
-
- std::optional<bool> TEventOutputChannel::FeedInlinePayload(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed) {
- if (task.GetInternalFreeAmount() <= sizeof(TChannelPart)) {
- return std::nullopt;
- }
-
- auto partBookmark = task.Bookmark(sizeof(TChannelPart));
-
- size_t bytesSerialized = 0;
- const bool complete = SerializeEvent<false>(task, event, &bytesSerialized);
-
- Y_DEBUG_ABORT_UNLESS(bytesSerialized);
- Y_ABORT_UNLESS(bytesSerialized <= Max<ui16>());
-
- TChannelPart part{
- .ChannelFlags = ChannelId,
- .Size = static_cast<ui16>(bytesSerialized)
- };
-
- task.WriteBookmark(std::move(partBookmark), &part, sizeof(part));
- *weightConsumed += sizeof(TChannelPart) + part.Size;
- OutputQueueSize -= part.Size;
-
- return complete;
- }
-
- std::optional<bool> TEventOutputChannel::FeedExternalPayload(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed) {
- const size_t partSize = sizeof(TChannelPart) + sizeof(ui8) + sizeof(ui16) + (Params.Encryption ? 0 : sizeof(ui32));
- if (task.GetInternalFreeAmount() < partSize || task.GetExternalFreeAmount() == 0) {
- return std::nullopt;
- }
-
- // clear external checksum for this chunk
- task.ExternalChecksum = 0;
-
- auto partBookmark = task.Bookmark(partSize);
-
- size_t bytesSerialized = 0;
- const bool complete = SerializeEvent<true>(task, event, &bytesSerialized);
-
- Y_ABORT_UNLESS(0 < bytesSerialized && bytesSerialized <= Max<ui16>());
-
- char buffer[partSize];
- TChannelPart *part = reinterpret_cast<TChannelPart*>(buffer);
- *part = {
- .ChannelFlags = static_cast<ui16>(ChannelId | TChannelPart::XdcFlag),
- .Size = static_cast<ui16>(partSize - sizeof(TChannelPart))
- };
- char *ptr = reinterpret_cast<char*>(part + 1);
- *ptr++ = static_cast<ui8>(EXdcCommand::PUSH_DATA);
- *reinterpret_cast<ui16*>(ptr) = bytesSerialized;
- ptr += sizeof(ui16);
- if (task.ChecksummingXxhash()) {
- XXH3_state_t state;
- XXH3_64bits_reset(&state);
- task.XdcStream.ScanLastBytes(bytesSerialized, [&state](TContiguousSpan span) {
- XXH3_64bits_update(&state, span.data(), span.size());
- });
- *reinterpret_cast<ui32*>(ptr) = XXH3_64bits_digest(&state);
- } else if (task.ChecksummingCrc32c()) {
- *reinterpret_cast<ui32*>(ptr) = task.ExternalChecksum;
- }
-
- task.WriteBookmark(std::move(partBookmark), buffer, partSize);
-
- *weightConsumed += partSize + bytesSerialized;
- OutputQueueSize -= bytesSerialized;
-
- return complete;
- }
-
- 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::BODY && Queue.front().Event) {
- Y_ABORT_UNLESS(!Chunker.IsComplete()); // chunk must have an event being serialized
- Y_ABORT_UNLESS(!Queue.empty()); // this event must be the first event in queue
- TEventHolder& event = Queue.front();
- Y_ABORT_UNLESS(Chunker.GetCurrentEvent() == event.Event.Get()); // ensure the event is valid
- Chunker.Abort(); // stop serializing current event
- Y_ABORT_UNLESS(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);
- }
-
-}
diff --git a/library/cpp/actors/interconnect/interconnect_channel.h b/library/cpp/actors/interconnect/interconnect_channel.h
deleted file mode 100644
index ef2da2fda7..0000000000
--- a/library/cpp/actors/interconnect/interconnect_channel.h
+++ /dev/null
@@ -1,159 +0,0 @@
-#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 <library/cpp/actors/wilson/wilson_span.h>
-
-#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 ChannelFlags;
- ui16 Size;
-
- static constexpr ui16 LastPartFlag = 0x8000;
- static constexpr ui16 XdcFlag = 0x4000;
- static constexpr ui16 ChannelMask = (1 << IEventHandle::ChannelBits) - 1;
-
- static_assert((LastPartFlag & ChannelMask) == 0);
- static_assert((XdcFlag & ChannelMask) == 0);
-
- ui16 GetChannel() const { return ChannelFlags & ChannelMask; }
- bool IsLastPart() const { return ChannelFlags & LastPartFlag; }
- bool IsXdc() const { return ChannelFlags & XdcFlag; }
-
- TString ToString() const {
- return TStringBuilder() << "{Channel# " << GetChannel()
- << " IsLastPart# " << IsLastPart()
- << " IsXdc# " << IsXdc()
- << " Size# " << Size << "}";
- }
- };
-
-#pragma pack(pop)
-
- enum class EXdcCommand : ui8 {
- DECLARE_SECTION = 1,
- PUSH_DATA,
- DECLARE_SECTION_INLINE,
- };
-
- 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)
- : TInterconnectLoggingBase(Sprintf("OutputChannel %" PRIu16 " [node %" PRIu32 "]", id, peerNodeId))
- , Pool(pool)
- , PeerNodeId(peerNodeId)
- , ChannelId(id)
- , Metrics(std::move(metrics))
- , 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(TEventDescr2);
- OutputQueueSize += bytes;
- if (event.Span = NWilson::TSpan(15 /*max verbosity*/, NWilson::TTraceId(ev.TraceId), "Interconnect.Queue")) {
- event.Span
- .Attribute("OutputQueueItems", static_cast<i64>(Queue.size()))
- .Attribute("OutputQueueSize", static_cast<i64>(OutputQueueSize));
- }
- return std::make_pair(bytes, &event);
- }
-
- void DropConfirmed(ui64 confirm);
-
- bool FeedBuf(TTcpPacketOutTask& task, ui64 serial, ui64 *weightConsumed);
-
- bool IsEmpty() const {
- return Queue.empty();
- }
-
- bool IsWorking() const {
- return !IsEmpty();
- }
-
- ui32 GetQueueSize() const {
- return (ui32)Queue.size();
- }
-
- ui64 GetBufferedAmountOfData() const {
- return OutputQueueSize;
- }
-
- 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,
- BODY,
- DESCRIPTOR,
- SECTIONS,
- };
- EState State = EState::INITIAL;
-
- protected:
- ui64 OutputQueueSize = 0;
-
- std::list<TEventHolder> Queue;
- std::list<TEventHolder> NotYetConfirmed;
- TRope::TConstIterator Iter;
- TCoroutineChunkSerializer Chunker;
- TEventSerializationInfo SerializationInfoContainer;
- const TEventSerializationInfo *SerializationInfo = nullptr;
- bool IsPartInline = false;
- size_t PartLenRemain = 0;
- size_t SectionIndex = 0;
- std::vector<char> XdcData;
-
- template<bool External>
- bool SerializeEvent(TTcpPacketOutTask& task, TEventHolder& event, size_t *bytesSerialized);
-
- bool FeedPayload(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed);
- std::optional<bool> FeedInlinePayload(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed);
- std::optional<bool> FeedExternalPayload(TTcpPacketOutTask& task, TEventHolder& event, ui64 *weightConsumed);
-
- 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
deleted file mode 100644
index 300153d8de..0000000000
--- a/library/cpp/actors/interconnect/interconnect_common.h
+++ /dev/null
@@ -1,140 +0,0 @@
-#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 "logging.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 {
- TDuration Handshake;
- TDuration DeadPeer;
- TDuration CloseOnIdle;
- ui32 SendBufferDieLimitInMB = 0;
- ui64 OutputBuffersTotalSizeLimitInMB = 0;
- ui32 TotalInflightAmountOfData = 0;
- bool MergePerPeerCounters = 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 PreallocatedBufferSize = 8 << 10; // 8 KB
- ui32 NumPreallocatedBuffers = 16;
- bool EnableExternalDataChannel = false;
- bool ValidateIncomingPeerViaDirectLookup = false;
- ui32 SocketBacklogSize = 0; // SOMAXCONN if zero
-
- ui32 GetSendBufferSize() const {
- ui32 res = 512 * 1024; // 512 kb is the default value for send buffer
- if (TCPSocketBufferSize) {
- res = TCPSocketBufferSize;
- }
- return res;
- }
- };
-
- struct TWhiteboardSessionStatus {
- TActorSystem* ActorSystem;
- ui32 PeerId;
- TString Peer;
- bool Connected;
- bool Green;
- bool Yellow;
- bool Orange;
- bool Red;
- i64 ClockSkew;
-
- TWhiteboardSessionStatus(TActorSystem* actorSystem, ui32 peerId, const TString& peer, bool connected, bool green, bool yellow, bool orange, bool red, i64 clockSkew)
- : ActorSystem(actorSystem)
- , PeerId(peerId)
- , Peer(peer)
- , Connected(connected)
- , Green(green)
- , Yellow(yellow)
- , Orange(orange)
- , Red(red)
- , ClockSkew(clockSkew)
- {}
- };
-
- 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 TWhiteboardSessionStatus& data)>;
-
- struct TInterconnectProxyCommon : TAtomicRefCount<TInterconnectProxyCommon> {
- TActorId NameserviceId;
- NMonitoring::TDynamicCounterPtr MonCounters;
- std::shared_ptr<NMonitoring::IMetricRegistry> Metrics;
- TChannelsConfig ChannelsConfig;
- TInterconnectSettings Settings;
- TRegisterMonPageCallback RegisterMonPage;
- TActorId DestructorId;
- std::shared_ptr<std::atomic<TAtomicBase>> DestructorQueueSize;
- TAtomicBase MaxDestructorQueueSize = 1024 * 1024 * 1024;
- TString ClusterUUID;
- TVector<TString> AcceptUUID;
- ui64 StartTime = GetCycleCountFast();
- TString TechnicalSelfHostName;
- TInitWhiteboardCallback InitWhiteboard;
- 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;
- std::optional<ui32> OutgoingHandshakeInflightLimit;
-
- 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
- };
-
- // obsolete compatibility control
- TMaybe<TVersionInfo> VersionInfo;
-
- std::optional<TString> CompatibilityInfo;
- std::function<bool(const TString&, TString&)> ValidateCompatibilityInfo;
- std::function<bool(const TInterconnectProxyCommon::TVersionInfo&, TString&)> ValidateCompatibilityOldFormat;
-
- using TPtr = TIntrusivePtr<TInterconnectProxyCommon>;
- };
-
-}
diff --git a/library/cpp/actors/interconnect/interconnect_counters.cpp b/library/cpp/actors/interconnect/interconnect_counters.cpp
deleted file mode 100644
index 1c55eab650..0000000000
--- a/library/cpp/actors/interconnect/interconnect_counters.cpp
+++ /dev/null
@@ -1,703 +0,0 @@
-#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 {
-
- 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;
- TOutputChannel &operator=(const TOutputChannel& other) = 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;
- TInputChannel &operator=(const TInputChannel& other) = 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;
- TInputChannels &operator=(const TInputChannels& other) = 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 {
- *InflightDataAmount += value;
- }
-
- void SubInflightDataAmount(ui64 value) override {
- *InflightDataAmount -= value;
- }
-
- void AddTotalBytesWritten(ui64 value) override {
- *TotalBytesWritten += value;
- }
-
- void SetClockSkewMicrosec(i64 value) override {
- *ClockSkewMicrosec = value;
- }
-
- void IncSessionDeaths() override {
- ++*SessionDeaths;
- }
-
- void IncHandshakeFails() override {
- ++*HandshakeFails;
- }
-
- void SetConnected(ui32 value) override {
- *Connected = value;
- }
-
- void IncSubscribersCount() override {
- ++*SubscribersCount;
- }
-
- void SubSubscribersCount(ui32 value) override {
- *SubscribersCount -= value;
- }
-
- void SubOutputBuffersTotalSize(ui64 value) override {
- *OutputBuffersTotalSize -= value;
- }
-
- void AddOutputBuffersTotalSize(ui64 value) override {
- *OutputBuffersTotalSize += value;
- }
-
- ui64 GetOutputBuffersTotalSize() const override {
- return *OutputBuffersTotalSize;
- }
-
- void IncDisconnections() override {
- ++*Disconnections;
- }
-
- void IncUsefulWriteWakeups() override {
- ++*UsefulWriteWakeups;
- }
-
- void IncSpuriousWriteWakeups() override {
- ++*SpuriousWriteWakeups;
- }
-
- void IncSendSyscalls(ui64 ns) override {
- ++*SendSyscalls;
- *SendSyscallsNs += ns;
- }
-
- void IncInflyLimitReach() override {
- ++*InflyLimitReach;
- }
-
- void IncUsefulReadWakeups() override {
- ++*UsefulReadWakeups;
- }
-
- void IncSpuriousReadWakeups() override {
- ++*SpuriousReadWakeups;
- }
-
- void IncDisconnectByReason(const TString& s) override {
- if (auto it = DisconnectByReason.find(s); it != DisconnectByReason.end()) {
- it->second->Inc();
- }
- }
-
- void AddInputChannelsIncomingTraffic(ui16 channel, ui64 incomingTraffic) override {
- auto& ch = InputChannels.Get(channel);
- *ch.IncomingTraffic += incomingTraffic;
- }
-
- void IncInputChannelsIncomingEvents(ui16 channel) override {
- auto& ch = InputChannels.Get(channel);
- ++*ch.IncomingEvents;
- }
-
- void IncRecvSyscalls(ui64 ns) override {
- ++*RecvSyscalls;
- *RecvSyscallsNs += ns;
- }
-
- void AddTotalBytesRead(ui64 value) override {
- *TotalBytesRead += value;
- }
-
- void UpdatePingTimeHistogram(ui64 value) override {
- PingTimeHistogram->Collect(value);
- }
-
- void UpdateOutputChannelTraffic(ui16 channel, ui64 value) override {
- auto& ch = GetOutputChannel(channel);
- if (ch.OutgoingTraffic) {
- *ch.OutgoingTraffic += value;
- }
- if (ch.Traffic) {
- *ch.Traffic += value;
- }
- }
-
- void UpdateOutputChannelEvents(ui16 channel) override {
- auto& ch = GetOutputChannel(channel);
- if (ch.OutgoingEvents) {
- ++*ch.OutgoingEvents;
- }
- if (ch.Events) {
- ++*ch.Events;
- }
- }
-
- void SetPeerInfo(const TString& name, const TString& dataCenterId) override {
- 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");
-
- PingTimeHistogram = AdaptiveCounters->GetHistogram(
- "PingTimeUs", NMonitoring::ExponentialHistogram(18, 2, 125));
- }
-
- if (updateGlobal) {
- OutputBuffersTotalSize = Counters->GetCounter("OutputBuffersTotalSize");
- SendSyscalls = Counters->GetCounter("SendSyscalls", true);
- SendSyscallsNs = Counters->GetCounter("SendSyscallsNs", true);
- RecvSyscalls = Counters->GetCounter("RecvSyscalls", true);
- RecvSyscallsNs = Counters->GetCounter("RecvSyscallsNs", 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;
- }
-
- const TOutputChannel& GetOutputChannel(ui16 index) const {
- Y_ABORT_UNLESS(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 SendSyscallsNs;
- NMonitoring::TDynamicCounters::TCounterPtr ClockSkewMicrosec;
- NMonitoring::TDynamicCounters::TCounterPtr RecvSyscalls;
- NMonitoring::TDynamicCounters::TCounterPtr RecvSyscallsNs;
- NMonitoring::TDynamicCounters::TCounterPtr UsefulReadWakeups;
- NMonitoring::TDynamicCounters::TCounterPtr SpuriousReadWakeups;
- NMonitoring::TDynamicCounters::TCounterPtr UsefulWriteWakeups;
- NMonitoring::TDynamicCounters::TCounterPtr SpuriousWriteWakeups;
- NMonitoring::THistogramPtr PingTimeHistogram;
-
- 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 {
- NMonitoring::IRate* Traffic;
- NMonitoring::IRate* Events;
- NMonitoring::IRate* OutgoingTraffic;
- NMonitoring::IRate* OutgoingEvents;
-
- TOutputChannel() = default;
-
- TOutputChannel(const std::shared_ptr<NMonitoring::IMetricRegistry>& metrics,
- NMonitoring::IRate* traffic,
- NMonitoring::IRate* events)
- : Traffic(traffic)
- , Events(events)
- , OutgoingTraffic(metrics->Rate(NMonitoring::MakeLabels({{"sensor", "interconnect.outgoing_traffic"}})))
- , OutgoingEvents(metrics->Rate(NMonitoring::MakeLabels({{"sensor", "interconnect.outgoing_events"}})))
- {}
-
- TOutputChannel(const TOutputChannel&) = default;
- TOutputChannel &operator=(const TOutputChannel& other) = default;
- };
-
- struct TInputChannel {
- NMonitoring::IRate* Traffic;
- NMonitoring::IRate* Events;
- NMonitoring::IRate* ScopeErrors;
- NMonitoring::IRate* IncomingTraffic;
- NMonitoring::IRate* IncomingEvents;
-
- TInputChannel() = default;
-
- TInputChannel(const std::shared_ptr<NMonitoring::IMetricRegistry>& metrics,
- NMonitoring::IRate* traffic, NMonitoring::IRate* events,
- NMonitoring::IRate* scopeErrors)
- : Traffic(traffic)
- , Events(events)
- , ScopeErrors(scopeErrors)
- , IncomingTraffic(metrics->Rate(NMonitoring::MakeLabels({{"sensor", "interconnect.incoming_traffic"}})))
- , IncomingEvents(metrics->Rate(NMonitoring::MakeLabels({{"sensor", "interconnect.incoming_events"}})))
- {}
-
- TInputChannel(const TInputChannel&) = default;
- TInputChannel &operator=(const TInputChannel& other) = default;
- };
-
- struct TInputChannels : std::unordered_map<ui16, TInputChannel> {
- TInputChannel OtherInputChannel;
-
- TInputChannels() = default;
-
- TInputChannels(const std::shared_ptr<NMonitoring::IMetricRegistry>& metrics,
- const std::unordered_map<ui16, TString>& names,
- NMonitoring::IRate* traffic, NMonitoring::IRate* events,
- NMonitoring::IRate* scopeErrors)
- : OtherInputChannel(std::make_shared<NMonitoring::TMetricSubRegistry>(
- NMonitoring::TLabels{{"channel", "other"}}, metrics), traffic, events, scopeErrors)
- {
- for (const auto& [id, name] : names) {
- try_emplace(id, std::make_shared<NMonitoring::TMetricSubRegistry>(NMonitoring::TLabels{{"channel", name}}, metrics),
- traffic, events, scopeErrors);
- }
- }
-
- TInputChannels(const TInputChannels&) = default;
- TInputChannels &operator=(const TInputChannels& other) = default;
-
- const TInputChannel& Get(ui16 id) const {
- const auto it = find(id);
- return it != end() ? it->second : OtherInputChannel;
- }
- };
-
- TInterconnectMetrics(const TInterconnectProxyCommon::TPtr& common)
- : Common(common)
- , MergePerDataCenterMetrics_(common->Settings.MergePerDataCenterCounters)
- , MergePerPeerMetrics_(common->Settings.MergePerPeerCounters)
- , Metrics_(common->Metrics)
- , AdaptiveMetrics_(MergePerDataCenterMetrics_
- ? PerDataCenterMetrics_ :
- MergePerPeerMetrics_ ? Metrics_ : PerSessionMetrics_)
- {}
-
- void AddInflightDataAmount(ui64 value) override {
- InflightDataAmount_->Add(value);
- }
-
- void SubInflightDataAmount(ui64 value) override {
- InflightDataAmount_->Add(-value);
- }
-
- void AddTotalBytesWritten(ui64 value) override {
- TotalBytesWritten_->Add(value);
- }
-
- void SetClockSkewMicrosec(i64 value) override {
- ClockSkewMicrosec_->Set(value);
- }
-
- void IncSessionDeaths() override {
- SessionDeaths_->Inc();
- }
-
- void IncHandshakeFails() override {
- HandshakeFails_->Inc();
- }
-
- void SetConnected(ui32 value) override {
- Connected_->Set(value);
- }
-
- void IncSubscribersCount() override {
- SubscribersCount_->Inc();
- }
-
- void SubSubscribersCount(ui32 value) override {
- SubscribersCount_->Add(-value);
- }
-
- void SubOutputBuffersTotalSize(ui64 value) override {
- OutputBuffersTotalSize_->Add(-value);
- }
-
- void AddOutputBuffersTotalSize(ui64 value) override {
- OutputBuffersTotalSize_->Add(value);
- }
-
- ui64 GetOutputBuffersTotalSize() const override {
- return OutputBuffersTotalSize_->Get();
- }
-
- void IncDisconnections() override {
- Disconnections_->Inc();
- }
-
- void IncUsefulWriteWakeups() override {
- UsefulWriteWakeups_->Inc();
- }
-
- void IncSpuriousWriteWakeups() override {
- SpuriousWriteWakeups_->Inc();
- }
-
- void IncSendSyscalls(ui64 /*ns*/) override {
- SendSyscalls_->Inc();
- }
-
- void IncInflyLimitReach() override {
- InflyLimitReach_->Inc();
- }
-
- void IncUsefulReadWakeups() override {
- UsefulReadWakeups_->Inc();
- }
-
- void IncSpuriousReadWakeups() override {
- SpuriousReadWakeups_->Inc();
- }
-
- void IncDisconnectByReason(const TString& s) override {
- if (auto it = DisconnectByReason_.find(s); it != DisconnectByReason_.end()) {
- it->second->Inc();
- }
- }
-
- void AddInputChannelsIncomingTraffic(ui16 channel, ui64 incomingTraffic) override {
- auto& ch = InputChannels_.Get(channel);
- ch.IncomingTraffic->Add(incomingTraffic);
- }
-
- void IncInputChannelsIncomingEvents(ui16 channel) override {
- auto& ch = InputChannels_.Get(channel);
- ch.IncomingEvents->Inc();
- }
-
- void IncRecvSyscalls(ui64 /*ns*/) override {
- RecvSyscalls_->Inc();
- }
-
- void AddTotalBytesRead(ui64 value) override {
- TotalBytesRead_->Add(value);
- }
-
- void UpdatePingTimeHistogram(ui64 value) override {
- PingTimeHistogram_->Record(value);
- }
-
- void UpdateOutputChannelTraffic(ui16 channel, ui64 value) override {
- auto& ch = GetOutputChannel(channel);
- if (ch.OutgoingTraffic) {
- ch.OutgoingTraffic->Add(value);
- }
- if (ch.Traffic) {
- ch.Traffic->Add(value);
- }
- }
-
- void UpdateOutputChannelEvents(ui16 channel) override {
- auto& ch = GetOutputChannel(channel);
- if (ch.OutgoingEvents) {
- ch.OutgoingEvents->Inc();
- }
- if (ch.Events) {
- ch.Events->Inc();
- }
- }
-
- void SetPeerInfo(const TString& name, const TString& dataCenterId) override {
- if (name != std::exchange(HumanFriendlyPeerHostName, name)) {
- PerSessionMetrics_.reset();
- }
- VALGRIND_MAKE_READABLE(&DataCenterId, sizeof(DataCenterId));
- if (dataCenterId != std::exchange(DataCenterId, dataCenterId)) {
- PerDataCenterMetrics_.reset();
- }
-
- const bool updatePerDataCenter = !PerDataCenterMetrics_ && MergePerDataCenterMetrics_;
- if (updatePerDataCenter) {
- PerDataCenterMetrics_ = std::make_shared<NMonitoring::TMetricSubRegistry>(
- NMonitoring::TLabels{{"datacenter_id", *DataCenterId}}, Metrics_);
- }
-
- const bool updatePerSession = !PerSessionMetrics_ || updatePerDataCenter;
- if (updatePerSession) {
- auto base = MergePerDataCenterMetrics_ ? PerDataCenterMetrics_ : Metrics_;
- PerSessionMetrics_ = std::make_shared<NMonitoring::TMetricSubRegistry>(
- NMonitoring::TLabels{{"peer", *HumanFriendlyPeerHostName}}, base);
- }
-
- const bool updateGlobal = !Initialized_;
-
- const bool updateAdaptive =
- &AdaptiveMetrics_ == &Metrics_ ? updateGlobal :
- &AdaptiveMetrics_ == &PerSessionMetrics_ ? updatePerSession :
- &AdaptiveMetrics_ == &PerDataCenterMetrics_ ? updatePerDataCenter :
- false;
-
- auto createRate = [](std::shared_ptr<NMonitoring::IMetricRegistry> metrics, TStringBuf name) mutable {
- return metrics->Rate(NMonitoring::MakeLabels(NMonitoring::TLabels{{"sensor", name}}));
- };
- auto createIntGauge = [](std::shared_ptr<NMonitoring::IMetricRegistry> metrics, TStringBuf name) mutable {
- return metrics->IntGauge(NMonitoring::MakeLabels(NMonitoring::TLabels{{"sensor", name}}));
- };
-
- if (updatePerSession) {
- Connected_ = createIntGauge(PerSessionMetrics_, "interconnect.connected");
- Disconnections_ = createRate(PerSessionMetrics_, "interconnect.disconnections");
- ClockSkewMicrosec_ = createIntGauge(PerSessionMetrics_, "interconnect.clock_skew_microsec");
- Traffic_ = createRate(PerSessionMetrics_, "interconnect.traffic");
- Events_ = createRate(PerSessionMetrics_, "interconnect.events");
- ScopeErrors_ = createRate(PerSessionMetrics_, "interconnect.scope_errors");
-
- for (const auto& [id, name] : Common->ChannelName) {
- OutputChannels_.try_emplace(id, std::make_shared<NMonitoring::TMetricSubRegistry>(
- NMonitoring::TLabels{{"channel", name}}, Metrics_), Traffic_, Events_);
- }
- OtherOutputChannel_ = TOutputChannel(std::make_shared<NMonitoring::TMetricSubRegistry>(
- NMonitoring::TLabels{{"channel", "other"}}, Metrics_), Traffic_, Events_);
-
- InputChannels_ = TInputChannels(Metrics_, Common->ChannelName, Traffic_, Events_, ScopeErrors_);
- }
-
- if (updateAdaptive) {
- SessionDeaths_ = createRate(AdaptiveMetrics_, "interconnect.session_deaths");
- HandshakeFails_ = createRate(AdaptiveMetrics_, "interconnect.handshake_fails");
- InflyLimitReach_ = createRate(AdaptiveMetrics_, "interconnect.infly_limit_reach");
- InflightDataAmount_ = createRate(AdaptiveMetrics_, "interconnect.inflight_data");
- PingTimeHistogram_ = AdaptiveMetrics_->HistogramRate(
- NMonitoring::MakeLabels({{"sensor", "interconnect.ping_time_us"}}), NMonitoring::ExponentialHistogram(18, 2, 125));
- }
-
- if (updateGlobal) {
- OutputBuffersTotalSize_ = createRate(Metrics_, "interconnect.output_buffers_total_size");
- SendSyscalls_ = createRate(Metrics_, "interconnect.send_syscalls");
- RecvSyscalls_ = createRate(Metrics_, "interconnect.recv_syscalls");
- SpuriousReadWakeups_ = createRate(Metrics_, "interconnect.spurious_read_wakeups");
- UsefulReadWakeups_ = createRate(Metrics_, "interconnect.useful_read_wakeups");
- SpuriousWriteWakeups_ = createRate(Metrics_, "interconnect.spurious_write_wakeups");
- UsefulWriteWakeups_ = createRate(Metrics_, "interconnect.useful_write_wakeups");
- SubscribersCount_ = createIntGauge(AdaptiveMetrics_, "interconnect.subscribers_count");
- TotalBytesWritten_ = createRate(Metrics_, "interconnect.total_bytes_written");
- TotalBytesRead_ = createRate(Metrics_, "interconnect.total_bytes_read");
-
- for (const char *reason : TDisconnectReason::Reasons) {
- DisconnectByReason_[reason] = Metrics_->Rate(
- NMonitoring::MakeLabels({
- {"sensor", "interconnect.disconnect_reason"},
- {"reason", reason},
- }));
- }
- }
-
- Initialized_ = true;
- }
-
- const TOutputChannel& GetOutputChannel(ui16 index) const {
- Y_ABORT_UNLESS(Initialized_);
- const auto it = OutputChannels_.find(index);
- return it != OutputChannels_.end() ? it->second : OtherOutputChannel_;
- }
-
- private:
- const TInterconnectProxyCommon::TPtr Common;
- const bool MergePerDataCenterMetrics_;
- const bool MergePerPeerMetrics_;
- std::shared_ptr<NMonitoring::IMetricRegistry> Metrics_;
- std::shared_ptr<NMonitoring::IMetricRegistry> PerSessionMetrics_;
- std::shared_ptr<NMonitoring::IMetricRegistry> PerDataCenterMetrics_;
- std::shared_ptr<NMonitoring::IMetricRegistry>& AdaptiveMetrics_;
- bool Initialized_ = false;
-
- NMonitoring::IRate* Traffic_;
-
- NMonitoring::IRate* Events_;
- NMonitoring::IRate* ScopeErrors_;
- NMonitoring::IRate* Disconnections_;
- NMonitoring::IIntGauge* Connected_;
-
- NMonitoring::IRate* SessionDeaths_;
- NMonitoring::IRate* HandshakeFails_;
- NMonitoring::IRate* InflyLimitReach_;
- NMonitoring::IRate* InflightDataAmount_;
- NMonitoring::IRate* OutputBuffersTotalSize_;
- NMonitoring::IIntGauge* SubscribersCount_;
- NMonitoring::IRate* SendSyscalls_;
- NMonitoring::IRate* RecvSyscalls_;
- NMonitoring::IRate* SpuriousWriteWakeups_;
- NMonitoring::IRate* UsefulWriteWakeups_;
- NMonitoring::IRate* SpuriousReadWakeups_;
- NMonitoring::IRate* UsefulReadWakeups_;
- NMonitoring::IIntGauge* ClockSkewMicrosec_;
-
- NMonitoring::IHistogram* PingTimeHistogram_;
-
- THashMap<ui16, TOutputChannel> OutputChannels_;
- TOutputChannel OtherOutputChannel_;
- TInputChannels InputChannels_;
-
- THashMap<TString, NMonitoring::IRate*> DisconnectByReason_;
-
- NMonitoring::IRate* TotalBytesWritten_;
- NMonitoring::IRate* TotalBytesRead_;
- };
-
-} // namespace
-
-std::unique_ptr<IInterconnectMetrics> CreateInterconnectCounters(const TInterconnectProxyCommon::TPtr& common) {
- return std::make_unique<TInterconnectCounters>(common);
-}
-
-std::unique_ptr<IInterconnectMetrics> CreateInterconnectMetrics(const TInterconnectProxyCommon::TPtr& common) {
- return std::make_unique<TInterconnectMetrics>(common);
-}
-
-} // NActors
diff --git a/library/cpp/actors/interconnect/interconnect_counters.h b/library/cpp/actors/interconnect/interconnect_counters.h
deleted file mode 100644
index 205ccf35b1..0000000000
--- a/library/cpp/actors/interconnect/interconnect_counters.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#pragma once
-
-#include <util/system/valgrind.h>
-
-#include "types.h"
-
-#include "interconnect_common.h"
-
-#include <memory>
-#include <optional>
-
-namespace NActors {
-
-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 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 IncDisconnections() = 0;
- virtual void IncUsefulWriteWakeups() = 0;
- virtual void IncSpuriousWriteWakeups() = 0;
- virtual void IncSendSyscalls(ui64 ns) = 0;
- virtual void IncInflyLimitReach() = 0;
- virtual void IncDisconnectByReason(const TString& s) = 0;
- 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 IncInputChannelsIncomingEvents(ui16 channel) = 0;
- virtual void IncRecvSyscalls(ui64 ns) = 0;
- virtual void AddTotalBytesRead(ui64 value) = 0;
- virtual void UpdatePingTimeHistogram(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());
- }
-
-protected:
- std::optional<TString> DataCenterId;
- std::optional<TString> HumanFriendlyPeerHostName;
-};
-
-std::unique_ptr<IInterconnectMetrics> CreateInterconnectCounters(const NActors::TInterconnectProxyCommon::TPtr& common);
-std::unique_ptr<IInterconnectMetrics> CreateInterconnectMetrics(const NActors::TInterconnectProxyCommon::TPtr& common);
-} // NActors
diff --git a/library/cpp/actors/interconnect/interconnect_handshake.cpp b/library/cpp/actors/interconnect/interconnect_handshake.cpp
deleted file mode 100644
index 8c347507b2..0000000000
--- a/library/cpp/actors/interconnect/interconnect_handshake.cpp
+++ /dev/null
@@ -1,1237 +0,0 @@
-#include "interconnect_handshake.h"
-#include "handshake_broker.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/random/entropy.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 {};
- struct TExPoison {};
-
- 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;
-
- 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;
-
- ui32 CalculateChecksum(const void* data, size_t len) const {
- return Crc32cExtendMSanCompatible(Crc32cExtendMSanCompatible(0, &Size, sizeof(Size)), data, len);
- }
-
- void Sign(const void* data, size_t len) {
- Checksum = CalculateChecksum(data, len);
- }
-
- bool Check(const void* data, size_t len) const {
- return Checksum == CalculateChecksum(data, len);
- }
- };
-
-#pragma pack(pop)
-
- private:
- class TConnection : TNonCopyable {
- THandshakeActor *Actor = nullptr;
- TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
- TPollerToken::TPtr PollerToken;
-
- public:
- TConnection(THandshakeActor *actor, TIntrusivePtr<NInterconnect::TStreamSocket> socket)
- : Actor(actor)
- , Socket(std::move(socket))
- {}
-
- void Connect(TString *peerAddr) {
- for (const NInterconnect::TAddress& address : Actor->ResolvePeer()) {
- // create the socket with matching address family
- int err = 0;
- Socket = NInterconnect::TStreamSocket::Make(address.GetFamily(), &err);
- if (err == EAFNOSUPPORT) {
- Reset();
- continue;
- } else if (*Socket == -1) {
- Actor->Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "System error: failed to create socket");
- }
-
- // extract peer address
- if (peerAddr) {
- *peerAddr = address.ToString();
- }
-
- // set up socket parameters
- SetupSocket();
-
- // start connecting
- err = -Socket->Connect(address);
- if (err == EINPROGRESS) {
- RegisterInPoller();
- WaitPoller(false, true, "WaitConnect");
- err = Socket->GetConnectStatus();
- } else if (!err) {
- RegisterInPoller();
- }
-
- // check if connection succeeded
- if (err) {
- Reset();
- } else {
- break;
- }
- }
-
- if (!Socket) {
- Actor->Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Couldn't connect to any resolved address", true);
- }
- }
-
- void Reset() {
- Socket.Reset();
- PollerToken.Reset();
- }
-
- void SetupSocket() {
- // switch to nonblocking mode
- try {
- SetNonBlock(*Socket);
- SetNoDelay(*Socket, true);
- } catch (...) {
- Actor->Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "System error: can't up nonblocking mode for socket");
- }
-
- // setup send buffer size
- Socket->SetSendBufferSize(Actor->Common->Settings.GetSendBufferSize());
- }
-
- void RegisterInPoller() {
- Y_ABORT_UNLESS(!PollerToken);
- const bool success = Actor->Send(MakePollerActorId(), new TEvPollerRegister(Socket, Actor->SelfActorId, Actor->SelfActorId));
- Y_ABORT_UNLESS(success);
- auto result = Actor->WaitForSpecificEvent<TEvPollerRegisterResult>("RegisterPoller");
- PollerToken = std::move(result->Get()->PollerToken);
- Y_ABORT_UNLESS(PollerToken);
- Y_ABORT_UNLESS(PollerToken->RefCount() == 1); // ensure exclusive ownership
- }
-
- void WaitPoller(bool read, bool write, TString state) {
- if (!PollerToken->RequestNotificationAfterWouldBlock(read, write)) {
- Actor->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_ABORT_UNLESS(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) {
- Actor->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));
- }
-
- void ResetPollerToken() {
- if (PollerToken) {
- Y_ABORT_UNLESS(PollerToken->RefCount() == 1);
- PollerToken.Reset(); // ensure we are going to destroy poller token here as we will re-register the socket within other actor
- }
- }
-
- TIntrusivePtr<NInterconnect::TStreamSocket>& GetSocketRef() { return Socket; }
- operator bool() const { return static_cast<bool>(Socket); }
- };
-
- 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;
- TConnection MainChannel;
- TConnection ExternalDataChannel;
- TString State;
- TString HandshakeKind;
- TMaybe<THolder<TProgramInfo>> ProgramInfo; // filled in in case of successful handshake; even if null
- TSessionParams Params;
- std::optional<TInstant> LastLogNotice;
- const TDuration MuteDuration = TDuration::Seconds(15);
- TMonotonic Deadline;
- TActorId HandshakeBroker;
- std::optional<TBrokerLeaseHolder> BrokerLeaseHolder;
- std::optional<TString> HandshakeId; // for XDC
- bool SubscribedForConnection = false;
-
- public:
- THandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self, const TActorId& peer,
- ui32 nodeId, ui64 nextPacket, TString peerHostName, TSessionParams params)
- : TActorCoroImpl(StackSize, true)
- , Common(std::move(common))
- , SelfVirtualId(self)
- , PeerVirtualId(peer)
- , PeerNodeId(nodeId)
- , NextPacketToPeer(nextPacket)
- , PeerHostName(std::move(peerHostName))
- , MainChannel(this, nullptr)
- , ExternalDataChannel(this, nullptr)
- , HandshakeKind("outgoing handshake")
- , Params(std::move(params))
- {
- Y_ABORT_UNLESS(SelfVirtualId);
- Y_ABORT_UNLESS(SelfVirtualId.NodeId());
- Y_ABORT_UNLESS(PeerNodeId);
- HandshakeBroker = MakeHandshakeBrokerOutId();
-
- // generate random handshake id
- HandshakeId = TString::Uninitialized(32);
- EntropyPool().Read(HandshakeId->Detach(), HandshakeId->size());
- }
-
- THandshakeActor(TInterconnectProxyCommon::TPtr common, TSocketPtr socket)
- : TActorCoroImpl(StackSize, true)
- , Common(std::move(common))
- , MainChannel(this, std::move(socket))
- , ExternalDataChannel(this, nullptr)
- , HandshakeKind("incoming handshake")
- {
- Y_ABORT_UNLESS(MainChannel);
- PeerAddr = TString::Uninitialized(1024);
- if (GetRemoteAddr(*MainChannel.GetSocketRef(), 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 {
- try {
- RunImpl();
- } catch (const TDtorException&) {
- if (BrokerLeaseHolder) {
- BrokerLeaseHolder->ForgetLease();
- }
- throw;
- } catch (const TExPoison&) {
- // just stop execution, do nothing
- } catch (...) {
- Y_ABORT("unhandled exception");
- }
- if (SubscribedForConnection) {
- SendToProxy(MakeHolder<TEvSubscribeForConnection>(*HandshakeId, false));
- }
- }
-
- void RunImpl() {
- UpdatePrefix();
-
- if (!MainChannel && Common->OutgoingHandshakeInflightLimit) {
- // Create holder, which sends request to broker and automatically frees the place when destroyed
- BrokerLeaseHolder.emplace(SelfActorId, HandshakeBroker);
- }
-
- if (BrokerLeaseHolder && BrokerLeaseHolder->IsLeaseRequested()) {
- WaitForSpecificEvent<TEvHandshakeBrokerPermit>("HandshakeBrokerPermit");
- }
-
- // set up overall handshake process timer
- TDuration timeout = Common->Settings.Handshake;
- if (timeout == TDuration::Zero()) {
- timeout = DEFAULT_HANDSHAKE_TIMEOUT;
- }
- timeout += ResolveTimeout * 2;
-
- if (MainChannel) {
- // Incoming handshakes have shorter timeout than outgoing
- timeout *= 0.9;
- }
-
- Deadline = TActivationContext::Monotonic() + timeout;
- Schedule(Deadline, new TEvents::TEvWakeup);
-
- try {
- const bool incoming = MainChannel;
- if (incoming) {
- PerformIncomingHandshake();
- } else {
- PerformOutgoingHandshake();
- }
-
- // establish encrypted channel, or, in case when encryption is disabled, check if it matches settings
- if (ProgramInfo) {
- if (Params.UseExternalDataChannel) {
- if (incoming) {
- Y_ABORT_UNLESS(SubscribedForConnection);
- auto ev = WaitForSpecificEvent<TEvReportConnection>("WaitInboundXdcStream");
- SubscribedForConnection = false;
- if (ev->Get()->HandshakeId != *HandshakeId) {
- Y_DEBUG_ABORT_UNLESS(false);
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Mismatching HandshakeId in external data channel");
- }
- ExternalDataChannel.GetSocketRef() = std::move(ev->Get()->Socket);
- } else {
- EstablishExternalDataChannel();
- }
- }
-
- if (Params.Encryption) {
- EstablishSecureConnection(MainChannel);
- if (ExternalDataChannel) {
- EstablishSecureConnection(ExternalDataChannel);
- }
- } 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_ABORT_UNLESS(NextPacketFromPeer);
- MainChannel.ResetPollerToken();
- ExternalDataChannel.ResetPollerToken();
- Y_ABORT_UNLESS(!ExternalDataChannel == !Params.UseExternalDataChannel);
- SendToProxy(MakeHolder<TEvHandshakeDone>(std::move(MainChannel.GetSocketRef()), PeerVirtualId, SelfVirtualId,
- *NextPacketFromPeer, ProgramInfo->Release(), std::move(Params), std::move(ExternalDataChannel.GetSocketRef())));
- }
-
- MainChannel.Reset();
- ExternalDataChannel.Reset();
- }
-
- void EstablishSecureConnection(TConnection& connection) {
- // wrap current socket with secure one
- connection.ResetPollerToken();
- TIntrusivePtr<NInterconnect::TStreamSocket>& socketRef = connection.GetSocketRef();
- auto ev = AskProxy<TEvSecureSocket>(MakeHolder<TEvGetSecureSocket>(socketRef), "AskProxy(TEvSecureContext)");
- TIntrusivePtr<NInterconnect::TSecureSocket> secure = std::move(ev->Get()->Socket); // remember for further use
- socketRef = secure; // replace the socket within the connection
- connection.RegisterInPoller(); // re-register in poller
-
- const ui32 myNodeId = GetActorSystem()->NodeId;
- const bool server = myNodeId < PeerNodeId; // keep server/client role permanent to enable easy TLS session resuming
- for (;;) {
- TString err;
- switch (secure->Establish(server, Params.AuthOnly, err)) {
- case NInterconnect::TSecureSocket::EStatus::SUCCESS:
- if (Params.AuthOnly) {
- Params.Encryption = false;
- Params.AuthCN = secure->GetPeerCommonName();
- connection.ResetPollerToken();
- socketRef = secure->Detach();
- connection.RegisterInPoller();
- }
- return;
-
- case NInterconnect::TSecureSocket::EStatus::ERROR:
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, err, true);
- [[fallthrough]];
-
- case NInterconnect::TSecureSocket::EStatus::WANT_READ:
- connection.WaitPoller(true, false, "ReadEstablish");
- break;
-
- case NInterconnect::TSecureSocket::EStatus::WANT_WRITE:
- connection.WaitPoller(false, true, "WriteEstablish");
- break;
- }
- }
- }
-
- void ProcessUnexpectedEvent(TAutoPtr<IEventHandle> ev) {
- 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;
-
- case TEvents::TSystem::Poison:
- throw TExPoison();
-
- default:
- Y_ABORT("unexpected event 0x%08" PRIx32, type);
- }
- }
-
- template<typename T>
- void SetupCompatibilityInfo(T& proto) {
- if (Common->CompatibilityInfo) {
- proto.SetCompatibilityInfo(*Common->CompatibilityInfo);
- }
- }
-
- 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 ValidateCompatibilityInfo(const T& proto, TCallback&& errorCallback) {
- // if possible, use new CompatibilityInfo field
- if (proto.HasCompatibilityInfo() && Common->ValidateCompatibilityInfo) {
- TString errorReason;
- if (!Common->ValidateCompatibilityInfo(proto.GetCompatibilityInfo(), errorReason)) {
- TStringStream s("Local and peer CompatibilityInfo are incompatible");
- s << ", errorReason# " << errorReason;
- errorCallback(s.Str());
- }
- } else if (proto.HasVersionTag() && Common->ValidateCompatibilityOldFormat) {
- TInterconnectProxyCommon::TVersionInfo oldFormat;
- oldFormat.Tag = proto.GetVersionTag();
- for (ui32 i = 0; i < proto.AcceptedVersionTagsSize(); ++i) {
- oldFormat.AcceptedTags.insert(proto.GetAcceptedVersionTags(i));
- }
- TString errorReason;
- if (!Common->ValidateCompatibilityOldFormat(oldFormat, errorReason)) {
- TStringStream s("Local CompatibilityInfo and peer TVersionInfo are incompatible");
- s << ", errorReason# " << errorReason;
- errorCallback(s.Str());
- }
- } else if (proto.HasVersionTag()) {
- ValidateVersionTag(proto, std::forward<TCallback>(errorCallback));
- } else {
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH09", NLog::PRI_WARN,
- "Neither CompatibilityInfo nor VersionTag of the peer can be validated, accepting by default");
- }
- }
-
- 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
- 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) {
- // 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
- TConnection tempConnection(this, nullptr);
- tempConnection.Connect(nullptr);
- SendInitialPacket(tempConnection);
-
- // wait for basic response
- TInitialPacket response;
- tempConnection.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(tempConnection, request, "ExBlockDoCheckCookie");
-
- // process cookie check reply
- NActorsInterconnect::THandshakeReply reply;
- if (!reply.ParseFromString(ReceiveExBlock(tempConnection, "ExBlockDoCheckCookie"))) {
- 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();
- return success;
- }
-
- void EstablishExternalDataChannel() {
- ExternalDataChannel.Connect(nullptr);
- char buf[12] = {'x', 'd', 'c', ' ', 'p', 'a', 'y', 'l', 'o', 'a', 'd', 0};
- TInitialPacket packet(TActorId(SelfActorId.NodeId(), TStringBuf(buf, 12)), {}, 0, INTERCONNECT_XDC_STREAM_VERSION);
- ExternalDataChannel.SendData(&packet, sizeof(packet), "SendXdcStream");
- NActorsInterconnect::TExternalDataChannelParams params;
- params.SetHandshakeId(*HandshakeId);
- SendExBlock(ExternalDataChannel, params, "ExternalDataChannelParams");
- }
-
- void PerformOutgoingHandshake() {
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH01", NLog::PRI_DEBUG,
- "starting outgoing handshake");
-
- // perform connection and log its result
- MainChannel.Connect(&PeerAddr);
- auto logPriority = std::exchange(LastLogNotice, std::nullopt) ? NActors::NLog::PRI_NOTICE : NActors::NLog::PRI_DEBUG;
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH05", logPriority, "connected to peer");
-
- // send initial request packet
- if (Params.UseExternalDataChannel && PeerVirtualId) { // special case for XDC continuation
- TInitialPacket packet(SelfVirtualId, PeerVirtualId, NextPacketToPeer, INTERCONNECT_XDC_CONTINUATION_VERSION);
- MainChannel.SendData(&packet, sizeof(packet), "SendInitialPacket");
- NActorsInterconnect::TContinuationParams request;
- request.SetHandshakeId(*HandshakeId);
- SendExBlock(MainChannel, request, "ExRequest");
- } else {
- TInitialPacket packet(SelfVirtualId, PeerVirtualId, NextPacketToPeer, INTERCONNECT_PROTOCOL_VERSION);
- MainChannel.SendData(&packet, sizeof(packet), "SendInitialPacket");
- }
-
- TInitialPacket response;
- MainChannel.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);
- SetupCompatibilityInfo(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);
- request.SetRequestExtendedTraceFmt(true);
- request.SetRequestExternalDataChannel(Common->Settings.EnableExternalDataChannel);
- request.SetRequestXxhash(true);
- request.SetRequestXdcShuffle(true);
- request.SetHandshakeId(*HandshakeId);
-
- SendExBlock(MainChannel, request, "ExRequest");
-
- NActorsInterconnect::THandshakeReply reply;
- if (!reply.ParseFromString(ReceiveExBlock(MainChannel, "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);
- ValidateCompatibilityInfo(success, generateError);
-
- const auto& s = success.GetSenderActorId();
- PeerVirtualId.Parse(s.data(), s.size());
-
- if (!success.GetUseModernFrame()) {
- generateError("UseModernFrame not set, obsolete peer version");
- } else if (!success.GetUseExtendedTraceFmt()) {
- generateError("UseExtendedTraceFmt not set, obsolete peer version");
- }
-
- // recover flags
- Params.Encryption = success.GetStartEncryption();
- Params.AuthOnly = Params.Encryption && success.GetAuthOnly();
- Params.UseExternalDataChannel = success.GetUseExternalDataChannel();
- Params.UseXxhash = success.GetUseXxhash();
- Params.UseXdcShuffle = success.GetUseXdcShuffle();
- 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
- }
- }
-
- std::vector<NInterconnect::TAddress> ResolvePeer() {
- // issue request to a nameservice to resolve peer node address
- const auto mono = TActivationContext::Monotonic();
- Send(Common->NameserviceId, new TEvInterconnect::TEvResolveNode(PeerNodeId, TActivationContext::Now() + (Deadline - mono)));
-
- // wait for the result
- auto ev = WaitForSpecificEvent<TEvResolveError, TEvLocalNodeInfo, TEvInterconnect::TEvNodeAddress>(
- "ValidateIncomingPeerViaDirectLookup", mono + ResolveTimeout);
-
- // extract address from the result
- std::vector<NInterconnect::TAddress> addresses;
- if (!ev) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve timed out", true);
- } else if (auto *p = ev->CastAsLocal<TEvLocalNodeInfo>()) {
- addresses = std::move(p->Addresses);
- if (addresses.empty()) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve error: no address returned", true);
- }
- } 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);
- }
- addresses.emplace_back(r.GetAddress(), static_cast<ui16>(r.GetPort()));
- } else {
- Y_ABORT_UNLESS(ev->GetTypeRewrite() == ui32(ENetwork::ResolveError));
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "DNS resolve error: " + ev->Get<TEvResolveError>()->Explain
- + ", Unresolved host# " + ev->Get<TEvResolveError>()->Host, true);
- }
-
- return addresses;
- }
-
- void ValidateIncomingPeerViaDirectLookup() {
- auto addresses = ResolvePeer();
-
- for (const auto& address : addresses) {
- if (address.GetAddress() == PeerAddr) {
- return;
- }
- }
-
- auto makeList = [&] {
- TStringStream s;
- s << '[';
- for (auto it = addresses.begin(); it != addresses.end(); ++it) {
- if (it != addresses.begin()) {
- s << ' ';
- }
- s << it->GetAddress();
- }
- s << ']';
- return s.Str();
- };
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, TStringBuilder() << "Connecting node does not resolve to peer address"
- << " PeerAddr# " << PeerAddr << " AddressList# " << makeList(), true);
- }
-
- void PerformIncomingHandshake() {
- LOG_LOG_IC_X(NActorsServices::INTERCONNECT, "ICH02", NLog::PRI_DEBUG,
- "starting incoming handshake");
-
- // set up incoming socket
- MainChannel.SetupSocket();
- MainChannel.RegisterInPoller();
-
- // wait for initial request packet
- TInitialPacket request;
- MainChannel.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 &&
- request.Header.Version != INTERCONNECT_XDC_CONTINUATION_VERSION &&
- request.Header.Version != INTERCONNECT_XDC_STREAM_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_DEBUG_ABORT_UNLESS(false, "PeerNodeId is zero request# %s", request.ToString().data());
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "SelfVirtualId.NodeId is empty in initial packet");
- }
- UpdatePrefix();
-
- // validate incoming peer if needed
- if (Common->Settings.ValidateIncomingPeerViaDirectLookup) {
- ValidateIncomingPeerViaDirectLookup();
- }
-
- // extract next packet
- NextPacketFromPeer = request.Header.NextPacket;
-
- // process some extra payload, if necessary
- switch (request.Header.Version) {
- case INTERCONNECT_XDC_CONTINUATION_VERSION: {
- NActorsInterconnect::TContinuationParams params;
- if (!params.ParseFromString(ReceiveExBlock(MainChannel, "ContinuationParams")) || !params.HasHandshakeId()) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Incorrect packet from peer");
- }
- HandshakeId = params.GetHandshakeId();
- SendToProxy(MakeHolder<TEvSubscribeForConnection>(*HandshakeId, true));
- SubscribedForConnection = true;
- break;
- }
- case INTERCONNECT_XDC_STREAM_VERSION: {
- NActorsInterconnect::TExternalDataChannelParams params;
- if (!params.ParseFromString(ReceiveExBlock(MainChannel, "ExternalDataChannelParams")) || !params.HasHandshakeId()) {
- Fail(TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT, "Incorrect packet from peer");
- }
- MainChannel.ResetPollerToken();
- SendToProxy(MakeHolder<TEvReportConnection>(params.GetHandshakeId(), std::move(MainChannel.GetSocketRef())));
- throw TExHandshakeFailed();
- }
- }
-
- 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(MainChannel);
- } else {
- // peer wants a new session, clear fields and send initial packet
- SelfVirtualId = TActorId();
- PeerVirtualId = TActorId();
- NextPacketToPeer = 0;
- SendInitialPacket(MainChannel);
-
- // wait for extended request
- auto ev = MakeHolder<TEvHandshakeRequest>();
- auto& request = ev->Record;
- if (!request.ParseFromString(ReceiveExBlock(MainChannel, "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(MainChannel, 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(MainChannel, 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) {
- generateError(Sprintf("ReceiverHostName# %s mismatch, expected# %s", request.GetReceiverHostName().data(),
- Common->TechnicalSelfHostName.data()));
- }
- ValidateCompatibilityInfo(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;
- }
-
- if (!request.GetRequestModernFrame()) {
- generateError("RequestModernFrame not set, obsolete peer version");
- } else if (!request.GetRequestExtendedTraceFmt()) {
- generateError("RequestExtendedTraceFmt not set, obsolete peer version");
- }
-
- Params.AuthOnly = Params.Encryption && request.GetRequestAuthOnly() && Common->Settings.TlsAuthOnly;
- Params.UseExternalDataChannel = request.GetRequestExternalDataChannel() && Common->Settings.EnableExternalDataChannel;
- Params.UseXxhash = request.GetRequestXxhash();
- Params.UseXdcShuffle = request.GetRequestXdcShuffle();
-
- if (Params.UseExternalDataChannel) {
- if (request.HasHandshakeId()) {
- HandshakeId = request.GetHandshakeId();
- SendToProxy(MakeHolder<TEvSubscribeForConnection>(*HandshakeId, true));
- SubscribedForConnection = true;
- } else {
- generateError("Peer has requested ExternalDataChannel feature, but did not provide HandshakeId");
- }
- }
-
- 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_ABORT_UNLESS(record.HasSuccess());
- auto& success = *record.MutableSuccess();
- SetupClusterUUID(success);
- SetupCompatibilityInfo(success);
- SetupVersionTag(success);
- success.SetStartEncryption(Params.Encryption);
- if (Common->LocalScopeId != TScopeId()) {
- FillInScopeId(*success.MutableServerScopeId());
- }
- success.SetUseModernFrame(true);
- success.SetAuthOnly(Params.AuthOnly);
- success.SetUseExtendedTraceFmt(true);
- success.SetUseExternalDataChannel(Params.UseExternalDataChannel);
- success.SetUseXxhash(Params.UseXxhash);
- success.SetUseXdcShuffle(Params.UseXdcShuffle);
- SendExBlock(MainChannel, 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(MainChannel, ev->Record, "ExReply");
- ProgramInfo.Clear(); // do not issue reply to the proxy
- } else {
- Y_ABORT("unexpected event Type# 0x%08" PRIx32, reply->GetTypeRewrite());
- }
- }
- }
-
- template <typename T>
- void SendExBlock(TConnection& connection, const T& proto, const char* what) {
- TString data;
- Y_PROTOBUF_SUPPRESS_NODISCARD proto.SerializeToString(&data);
- Y_ABORT_UNLESS(data.size() <= TExHeader::MaxSize);
-
- ReportProto(proto, Sprintf("SendExBlock %s", what).data());
-
- TExHeader header;
- header.Size = data.size();
- header.Sign(data.data(), data.size());
- connection.SendData(&header, sizeof(header), Sprintf("Send%sHeader", what));
- connection.SendData(data.data(), data.size(), Sprintf("Send%sData", what));
- }
-
- TString ReceiveExBlock(TConnection& connection, const char* what) {
- TExHeader header;
- connection.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);
- connection.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_ABORT_UNLESS(PeerNodeId);
- Send(GetActorSystem()->InterconnectProxy(PeerNodeId), ev.Release());
- }
-
- template <typename TEvent>
- THolder<typename TEvent::THandle> WaitForSpecificEvent(TString state, TMonotonic deadline = TMonotonic::Max()) {
- State = std::move(state);
- return TActorCoroImpl::WaitForSpecificEvent<TEvent>(&THandshakeActor::ProcessUnexpectedEvent, deadline);
- }
-
- template <typename T1, typename T2, typename... TEvents>
- THolder<IEventHandle> WaitForSpecificEvent(TString state, TMonotonic deadline = TMonotonic::Max()) {
- State = std::move(state);
- return TActorCoroImpl::WaitForSpecificEvent<T1, T2, TEvents...>(&THandshakeActor::ProcessUnexpectedEvent, 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", HandshakeKind.data(), PeerHostName ? PeerHostName.data() : "<unknown>",
- PeerAddr.size() ? PeerAddr.data() : "<unknown>", explanation.data());
-
- if (network) {
- TInstant now = Now();
- NActors::NLog::EPriority logPriority = NActors::NLog::PRI_DEBUG;
- if (!LastLogNotice || now - *LastLogNotice > MuteDuration) {
- logPriority = NActors::NLog::PRI_NOTICE;
- LastLogNotice.emplace(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 SendInitialPacket(TConnection& connection) {
- TInitialPacket packet(SelfVirtualId, PeerVirtualId, NextPacketToPeer, INTERCONNECT_PROTOCOL_VERSION);
- connection.SendData(&packet, sizeof(packet), "SendInitialPacket");
- }
-
- THolder<TEvInterconnect::TNodeInfo> GetPeerNodeInfo() {
- Y_ABORT_UNLESS(PeerNodeId);
- Send(Common->NameserviceId, new TEvInterconnect::TEvGetNode(PeerNodeId, TActivationContext::Now() +
- (Deadline - TActivationContext::Monotonic())));
- 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;
- }
- };
-
- 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::EActivityType::INTERCONNECT_HANDSHAKE);
- }
-
- IActor* CreateIncomingHandshakeActor(TInterconnectProxyCommon::TPtr common, TSocketPtr socket) {
- return new TActorCoro(MakeHolder<THandshakeActor>(std::move(common), std::move(socket)),
- IActor::EActivityType::INTERCONNECT_HANDSHAKE);
- }
-
-}
diff --git a/library/cpp/actors/interconnect/interconnect_handshake.h b/library/cpp/actors/interconnect/interconnect_handshake.h
deleted file mode 100644
index c8a7437b80..0000000000
--- a/library/cpp/actors/interconnect/interconnect_handshake.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#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 {
- static constexpr TDuration DEFAULT_HANDSHAKE_TIMEOUT = TDuration::Seconds(5);
- static constexpr ui64 INTERCONNECT_PROTOCOL_VERSION = 2;
- static constexpr ui64 INTERCONNECT_XDC_CONTINUATION_VERSION = 3;
- static constexpr ui64 INTERCONNECT_XDC_STREAM_VERSION = 4;
-
- 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);
-
-}
diff --git a/library/cpp/actors/interconnect/interconnect_impl.h b/library/cpp/actors/interconnect/interconnect_impl.h
deleted file mode 100644
index db598546cc..0000000000
--- a/library/cpp/actors/interconnect/interconnect_impl.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#pragma once
-
-#include "interconnect.h"
-#include <library/cpp/actors/protos/interconnect.pb.h>
-#include <library/cpp/actors/core/event_pb.h>
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-
-namespace NActors {
- // resolve node info
- struct TEvInterconnect::TEvResolveNode: public TEventPB<TEvInterconnect::TEvResolveNode, NActorsInterconnect::TEvResolveNode, TEvInterconnect::EvResolveNode> {
- TEvResolveNode() {
- }
-
- TEvResolveNode(ui32 nodeId, TInstant deadline = TInstant::Max()) {
- Record.SetNodeId(nodeId);
- 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
deleted file mode 100644
index f8245e1d72..0000000000
--- a/library/cpp/actors/interconnect/interconnect_mon.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-#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> {
- const TActorId Sender;
- const bool Json;
- TMap<ui32, TInterconnectProxyTCP::TProxyStats> Stats;
- ui32 PendingReplies = 0;
-
- public:
- static constexpr IActor::EActorActivity ActorActivityType() {
- return EActivityType::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 << "XDC"; }
- 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.ExternalDataChannel ? "yes" : "no"); }
- 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(ExternalDataChannel, 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 EActivityType::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
diff --git a/library/cpp/actors/interconnect/interconnect_mon.h b/library/cpp/actors/interconnect/interconnect_mon.h
deleted file mode 100644
index 3fb26053fb..0000000000
--- a/library/cpp/actors/interconnect/interconnect_mon.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-#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};
- return NActors::TActorId(nodeId, TStringBuf(s, 12));
- }
-
-} // NInterconnect
diff --git a/library/cpp/actors/interconnect/interconnect_nameserver_base.h b/library/cpp/actors/interconnect/interconnect_nameserver_base.h
deleted file mode 100644
index f9ce456d1c..0000000000
--- a/library/cpp/actors/interconnect/interconnect_nameserver_base.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "interconnect.h"
-#include "interconnect_impl.h"
-#include "interconnect_address.h"
-#include "events_local.h"
-
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/memory_log/memlog.h>
-
-namespace NActors {
-
- template<typename TDerived>
- class TInterconnectNameserverBase : public TActor<TDerived> {
- protected:
- const TMap<ui32, TTableNameserverSetup::TNodeInfo>& NodeTable;
-
- TInterconnectNameserverBase(void (TDerived::*func)(TAutoPtr<IEventHandle>& ev)
- , const TMap<ui32, TTableNameserverSetup::TNodeInfo>& nodeTable)
- : TActor<TDerived>(func)
- , NodeTable(nodeTable)
- {
- }
- public:
-
- void HandleMissedNodeId(TEvInterconnect::TEvResolveNode::TPtr& ev,
- const TActorContext& ctx,
- const TInstant&) {
- auto reply = new TEvLocalNodeInfo;
- reply->NodeId = ev->Get()->Record.GetNodeId();
- ctx.Send(ev->Sender, reply);
- }
-
- void Handle(TEvInterconnect::TEvResolveNode::TPtr& ev,
- const TActorContext& ctx) {
- const TEvInterconnect::TEvResolveNode* request = ev->Get();
- auto& record = request->Record;
- const ui32 nodeId = record.GetNodeId();
- const TInstant deadline = record.HasDeadline() ? TInstant::FromValue(record.GetDeadline()) : TInstant::Max();
- auto it = NodeTable.find(nodeId);
-
- if (it == NodeTable.end()) {
- static_cast<TDerived*>(this)->HandleMissedNodeId(ev, ctx, deadline);
- } else {
- IActor::RegisterWithSameMailbox(
- CreateResolveActor(nodeId, it->second, ev->Sender, this->SelfId(), deadline));
- }
- }
-
- void Handle(TEvResolveAddress::TPtr& ev,
- const TActorContext&) {
- const TEvResolveAddress* request = ev->Get();
-
- IActor::RegisterWithSameMailbox(
- CreateResolveActor(request->Address, request->Port, ev->Sender, this->SelfId(), TInstant::Max()));
- }
-
- void Handle(TEvInterconnect::TEvListNodes::TPtr& ev,
- const TActorContext& ctx) {
- THolder<TEvInterconnect::TEvNodesInfo>
- reply(new TEvInterconnect::TEvNodesInfo());
- reply->Nodes.reserve(NodeTable.size());
- for (const auto& pr : NodeTable) {
- reply->Nodes.emplace_back(pr.first,
- pr.second.Address, pr.second.Host, pr.second.ResolveHost,
- pr.second.Port, pr.second.Location);
- }
- ctx.Send(ev->Sender, reply.Release());
- }
-
- void Handle(TEvInterconnect::TEvGetNode::TPtr& ev,
- const TActorContext& ctx) {
- ui32 nodeId = ev->Get()->NodeId;
- THolder<TEvInterconnect::TEvNodeInfo>
- reply(new TEvInterconnect::TEvNodeInfo(nodeId));
- auto it = NodeTable.find(nodeId);
- if (it != NodeTable.end()) {
- reply->Node = MakeHolder<TEvInterconnect::TNodeInfo>(it->first, it->second.Address,
- it->second.Host, it->second.ResolveHost,
- it->second.Port, it->second.Location);
- }
- ctx.Send(ev->Sender, reply.Release());
- }
- };
-}
diff --git a/library/cpp/actors/interconnect/interconnect_nameserver_dynamic.cpp b/library/cpp/actors/interconnect/interconnect_nameserver_dynamic.cpp
deleted file mode 100644
index 867b4b5d39..0000000000
--- a/library/cpp/actors/interconnect/interconnect_nameserver_dynamic.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "interconnect.h"
-#include "interconnect_impl.h"
-#include "interconnect_address.h"
-#include "interconnect_nameserver_base.h"
-#include "events_local.h"
-#include "logging.h"
-
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/log.h>
-
-namespace NActors {
-
- class TInterconnectDynamicNameserver
- : public TInterconnectNameserverBase<TInterconnectDynamicNameserver>
- , public TInterconnectLoggingBase
- {
- struct TPendingRequest {
- TEvInterconnect::TEvResolveNode::TPtr Request;
- TInstant Deadline;
-
- TPendingRequest(TEvInterconnect::TEvResolveNode::TPtr request, const TInstant& deadline)
- : Request(request), Deadline(deadline)
- {
- }
- };
-
- TMap<ui32, TTableNameserverSetup::TNodeInfo> NodeTable;
- TVector<TPendingRequest> PendingRequests;
- TDuration PendingPeriod;
-
- void PrintInfo() {
- TString logMsg = TStringBuilder() << "Table size: " << NodeTable.size();
- for (const auto& [nodeId, node] : NodeTable) {
- TString str = TStringBuilder() << "\n > Node " << nodeId << " `" << node.Address << "`:" << node.Port << ", host: " << node.Host << ", resolveHost: " << node.ResolveHost;
- logMsg += str;
- }
- LOG_TRACE_IC("ICN01", "%s", logMsg.c_str());
- }
-
- bool IsNodeUpdated(const ui32 nodeId, const TString& address, const ui32 port) {
- bool printInfo = false;
- auto it = NodeTable.find(nodeId);
- if (it == NodeTable.end()) {
- LOG_TRACE_IC("ICN02", "New node %u `%s`: %u",
- nodeId, address.c_str(), port);
- printInfo = true;
- } else if (it->second.Address != address || it->second.Port != port) {
- LOG_TRACE_IC("ICN03", "Updated node %u `%s`: %u (from `%s`: %u)",
- nodeId, address.c_str(), port, it->second.Address.c_str(), it->second.Port);
- printInfo = true;
- Send(TActivationContext::InterconnectProxy(nodeId), new TEvInterconnect::TEvDisconnect);
- }
- return printInfo;
- }
-
- void DiscardTimedOutRequests(const TActorContext& ctx, ui32 compactionCount = 0) {
-
- auto now = Now();
-
- for (auto& pending : PendingRequests) {
- if (pending.Request && pending.Deadline > now) {
- LOG_ERROR_IC("ICN06", "Unknown nodeId: %u", pending.Request->Get()->Record.GetNodeId());
- auto reply = new TEvLocalNodeInfo;
- reply->NodeId = pending.Request->Get()->Record.GetNodeId();
- ctx.Send(pending.Request->Sender, reply);
- pending.Request.Reset();
- compactionCount++;
- }
- }
-
- if (compactionCount) {
- TVector<TPendingRequest> requests;
- if (compactionCount < PendingRequests.size()) { // sanity check
- requests.reserve(PendingRequests.size() - compactionCount);
- }
- for (auto& pending : PendingRequests) {
- if (pending.Request) {
- requests.emplace_back(pending.Request, pending.Deadline);
- }
- }
- PendingRequests.swap(requests);
- }
- }
-
- void SchedulePeriodic() {
- Schedule(TDuration::MilliSeconds(200), new TEvents::TEvWakeup());
- }
-
- public:
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::NAMESERVICE;
- }
-
- TInterconnectDynamicNameserver(const TIntrusivePtr<TTableNameserverSetup>& setup, const TDuration& pendingPeriod, ui32 /*resolvePoolId*/ )
- : TInterconnectNameserverBase<TInterconnectDynamicNameserver>(&TInterconnectDynamicNameserver::StateFunc, NodeTable)
- , NodeTable(setup->StaticNodeTable)
- , PendingPeriod(pendingPeriod)
- {
- Y_ABORT_UNLESS(setup->IsEntriesUnique());
- }
-
- STFUNC(StateFunc) {
- try {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvResolveNode, Handle);
- HFunc(TEvResolveAddress, Handle);
- HFunc(TEvInterconnect::TEvListNodes, Handle);
- HFunc(TEvInterconnect::TEvGetNode, Handle);
- HFunc(TEvInterconnect::TEvNodesInfo, HandleUpdate);
- CFunc(TEvents::TEvWakeup::EventType, HandlePeriodic);
- }
- } catch (...) {
- LOG_ERROR_IC("ICN09", "%s", CurrentExceptionMessage().c_str());
- }
- }
-
- void HandleMissedNodeId(TEvInterconnect::TEvResolveNode::TPtr& ev,
- const TActorContext& ctx,
- const TInstant& deadline) {
- if (PendingPeriod) {
- if (PendingRequests.size() == 0) {
- SchedulePeriodic();
- }
- PendingRequests.emplace_back(std::move(ev), Min(deadline, Now() + PendingPeriod));
- } else {
- LOG_ERROR_IC("ICN07", "Unknown nodeId: %u", ev->Get()->Record.GetNodeId());
- TInterconnectNameserverBase::HandleMissedNodeId(ev, ctx, deadline);
- }
- }
-
- void HandleUpdate(TEvInterconnect::TEvNodesInfo::TPtr& ev,
- const TActorContext& ctx) {
-
- auto request = ev->Get();
- LOG_TRACE_IC("ICN04", "Update TEvNodesInfo with sz: %lu ", request->Nodes.size());
-
- bool printInfo = false;
- ui32 compactionCount = 0;
-
- for (const auto& node : request->Nodes) {
- printInfo |= IsNodeUpdated(node.NodeId, node.Address, node.Port);
-
- NodeTable[node.NodeId] = TTableNameserverSetup::TNodeInfo(
- node.Address, node.Host, node.ResolveHost, node.Port, node.Location);
-
- for (auto& pending : PendingRequests) {
- if (pending.Request && pending.Request->Get()->Record.GetNodeId() == node.NodeId) {
- LOG_TRACE_IC("ICN05", "Pending nodeId: %u discovered", node.NodeId);
- RegisterWithSameMailbox(
- CreateResolveActor(node.NodeId, NodeTable[node.NodeId], pending.Request->Sender, SelfId(), pending.Deadline));
- pending.Request.Reset();
- compactionCount++;
- }
- }
- }
-
- if (printInfo) {
- PrintInfo();
- }
-
- DiscardTimedOutRequests(ctx, compactionCount);
- }
-
- void HandlePeriodic(const TActorContext& ctx) {
- DiscardTimedOutRequests(ctx, 0);
- if (PendingRequests.size()) {
- SchedulePeriodic();
- }
- }
- };
-
- IActor* CreateDynamicNameserver(const TIntrusivePtr<TTableNameserverSetup>& setup,
- const TDuration& pendingPeriod,
- ui32 poolId) {
- return new TInterconnectDynamicNameserver(setup, pendingPeriod, poolId);
- }
-
-}
diff --git a/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp b/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
deleted file mode 100644
index ac565f6f8c..0000000000
--- a/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#include "interconnect.h"
-#include "interconnect_impl.h"
-#include "interconnect_address.h"
-#include "interconnect_nameserver_base.h"
-#include "events_local.h"
-
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/memory_log/memlog.h>
-
-namespace NActors {
-
- class TInterconnectNameserverTable: public TInterconnectNameserverBase<TInterconnectNameserverTable> {
- TIntrusivePtr<TTableNameserverSetup> Config;
-
- public:
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::NAMESERVICE;
- }
-
- TInterconnectNameserverTable(const TIntrusivePtr<TTableNameserverSetup>& setup, ui32 /*resolvePoolId*/)
- : TInterconnectNameserverBase<TInterconnectNameserverTable>(&TInterconnectNameserverTable::StateFunc, setup->StaticNodeTable)
- , Config(setup)
- {
- Y_ABORT_UNLESS(Config->IsEntriesUnique());
- }
-
- STFUNC(StateFunc) {
- try {
- switch (ev->GetTypeRewrite()) {
- HFunc(TEvInterconnect::TEvResolveNode, Handle);
- HFunc(TEvResolveAddress, Handle);
- HFunc(TEvInterconnect::TEvListNodes, Handle);
- HFunc(TEvInterconnect::TEvGetNode, Handle);
- }
- } catch (...) {
- // on error - do nothing
- }
- }
- };
-
- 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;
- };
-
- Sort(infos, CompareHostLambda);
-
- for (ui32 idx = 1, end = StaticNodeTable.size(); idx < end; ++idx) {
- const TNodeInfo* left = infos[idx - 1];
- const TNodeInfo* right = infos[idx];
- if (left->ResolveHost == right->ResolveHost && left->Port == right->Port)
- return false;
- }
-
- 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
deleted file mode 100644
index 2c02c632c2..0000000000
--- a/library/cpp/actors/interconnect/interconnect_proxy_wrapper.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "interconnect_proxy_wrapper.h"
-#include "interconnect_tcp_proxy.h"
-#include <library/cpp/actors/interconnect/mock/ic_mock.h>
-
-namespace NActors {
-
- class TInterconnectProxyWrapper : public IActorCallback {
- TIntrusivePtr<TInterconnectProxyCommon> Common;
- const ui32 NodeId;
- TInterconnectMock *Mock;
- IActor *Proxy = nullptr;
-
- public:
- TInterconnectProxyWrapper(TIntrusivePtr<TInterconnectProxyCommon> common, ui32 nodeId, TInterconnectMock *mock)
- : IActorCallback(static_cast<TReceiveFunc>(&TInterconnectProxyWrapper::StateFunc), EActivityType::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_ABORT_UNLESS(Proxy);
- }
- InvokeOtherActor(*Proxy, &IActor::Receive, ev);
- }
- }
- };
-
- 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
deleted file mode 100644
index e5942351a7..0000000000
--- a/library/cpp/actors/interconnect/interconnect_proxy_wrapper.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#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_resolve.cpp b/library/cpp/actors/interconnect/interconnect_resolve.cpp
deleted file mode 100644
index 071af2f7c4..0000000000
--- a/library/cpp/actors/interconnect/interconnect_resolve.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-#include "interconnect.h"
-#include "interconnect_address.h"
-#include "events_local.h"
-#include "logging.h"
-
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/dnsresolver/dnsresolver.h>
-
-namespace NActors {
-
- using namespace NActors::NDnsResolver;
-
- class TInterconnectResolveActor
- : public TActorBootstrapped<TInterconnectResolveActor>
- , public TInterconnectLoggingBase
- {
- public:
- TInterconnectResolveActor(
- const TString& host, ui16 port, ui32 nodeId, const TString& defaultAddress,
- const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline)
- : Host(host)
- , NodeId(nodeId)
- , Port(port)
- , DefaultAddress(defaultAddress)
- , ReplyTo(replyTo)
- , ReplyFrom(replyFrom)
- , Deadline(deadline)
- { }
-
- TInterconnectResolveActor(
- const TString& host, ui16 port,
- const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline)
- : Host(host)
- , Port(port)
- , ReplyTo(replyTo)
- , ReplyFrom(replyFrom)
- , Deadline(deadline)
- { }
-
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::NAMESERVICE;
- }
-
- void Bootstrap() {
- TMaybe<TString> errorText;
- if (auto addr = ExtractDefaultAddr(errorText)) {
- LOG_TRACE_IC("ICR01", "Host: %s, CACHED address: %s", Host.c_str(), DefaultAddress.c_str());
- if (NodeId) {
- return SendLocalNodeInfoAndDie({{*addr}});
- } else {
- return SendAddressInfoAndDie(std::move(addr));
- }
- }
-
- if (errorText) {
- SendErrorAndDie(*errorText);
- }
-
- auto now = TActivationContext::Now();
- if (Deadline < now) {
- SendErrorAndDie("Deadline");
- return;
- }
-
- LOG_DEBUG_IC("ICR02", "Host: %s, RESOLVING address ...", Host.c_str());
- Send(MakeDnsResolverActorId(),
- NodeId
- ? static_cast<IEventBase*>(new TEvDns::TEvGetHostByName(Host, AF_UNSPEC))
- : static_cast<IEventBase*>(new TEvDns::TEvGetAddr(Host, AF_UNSPEC)),
- IEventHandle::FlagTrackDelivery);
-
- if (Deadline != TInstant::Max()) {
- Schedule(Deadline, new TEvents::TEvWakeup);
- }
-
- Become(&TThis::StateWork);
- }
-
- STRICT_STFUNC(StateWork, {
- sFunc(TEvents::TEvWakeup, HandleTimeout);
- sFunc(TEvents::TEvUndelivered, HandleUndelivered);
- hFunc(TEvDns::TEvGetAddrResult, Handle);
- hFunc(TEvDns::TEvGetHostByNameResult, Handle);
- });
-
- void HandleTimeout() {
- SendErrorAndDie("Deadline");
- }
-
- void HandleUndelivered() {
- SendErrorAndDie("Dns resolver is unavailable");
- }
-
- void Handle(TEvDns::TEvGetAddrResult::TPtr& ev) {
- if (auto addr = ExtractAddr(ev->Get())) {
- SendAddressInfoAndDie(std::move(addr));
- } else {
- SendErrorAndDie(ev->Get()->ErrorText);
- }
- }
-
- void Handle(TEvDns::TEvGetHostByNameResult::TPtr& ev) {
- auto& msg = *ev->Get();
- if (msg.Status) {
- SendErrorAndDie(msg.ErrorText);
- } else {
- std::vector<NInterconnect::TAddress> addresses;
- for (const auto& ipv6 : msg.AddrsV6) {
- addresses.emplace_back(ipv6, Port);
- }
- for (const auto& ipv4 : msg.AddrsV4) {
- addresses.emplace_back(ipv4, Port);
- }
- SendLocalNodeInfoAndDie(std::move(addresses));
- }
- }
-
- void SendAddressInfoAndDie(NAddr::IRemoteAddrPtr addr) {
- LOG_DEBUG_IC("ICR03", "Host: %s, RESOLVED address", Host.c_str());
- auto reply = new TEvAddressInfo;
- reply->Address = std::move(addr);
- TActivationContext::Send(new IEventHandle(ReplyTo, ReplyFrom, reply));
- PassAway();
- }
-
- void SendLocalNodeInfoAndDie(std::vector<NInterconnect::TAddress> addresses) {
- LOG_DEBUG_IC("ICR04", "Host: %s, RESOLVED address", Host.c_str());
- auto reply = std::make_unique<TEvLocalNodeInfo>();
- reply->NodeId = *NodeId;
- reply->Addresses = std::move(addresses);
- TActivationContext::Send(new IEventHandle(ReplyTo, ReplyFrom, reply.release()));
- PassAway();
- }
-
- void SendErrorAndDie(const TString& errorText) {
- LOG_DEBUG_IC("ICR05", "Host: %s, ERROR resolving: %s", Host.c_str(), errorText.c_str());
- auto *event = new TEvResolveError;
- event->Explain = errorText;
- event->Host = Host;
- TActivationContext::Send(new IEventHandle(ReplyTo, ReplyFrom, event));
- PassAway();
- }
-
- NAddr::IRemoteAddrPtr ExtractAddr(TEvDns::TEvGetAddrResult* msg) {
- if (msg->Status == 0) {
- if (msg->IsV6()) {
- struct sockaddr_in6 sin6;
- Zero(sin6);
- sin6.sin6_family = AF_INET6;
- sin6.sin6_addr = msg->GetAddrV6();
- sin6.sin6_port = HostToInet(Port);
- return MakeHolder<NAddr::TIPv6Addr>(sin6);
- }
-
- if (msg->IsV4()) {
- return MakeHolder<NAddr::TIPv4Addr>(TIpAddress(msg->GetAddrV4().s_addr, Port));
- }
-
- Y_ABORT("Unexpected result address family");
- }
-
- return nullptr;
- }
-
- NAddr::IRemoteAddrPtr ExtractDefaultAddr(TMaybe<TString>& errorText) {
- if (DefaultAddress) {
- NInterconnect::TAddress address(DefaultAddress.data(), Port);
-
- switch (address.GetFamily()) {
- case AF_INET:
- return MakeHolder<NAddr::TIPv4Addr>(*(sockaddr_in*)address.SockAddr());
- case AF_INET6:
- return MakeHolder<NAddr::TIPv6Addr>(*(sockaddr_in6*)address.SockAddr());
- default:
- errorText = "Unsupported default address: " + DefaultAddress;
- break;
- }
- }
-
- return nullptr;
- }
-
- private:
- const TString Host;
- const std::optional<ui32> NodeId;
- const ui16 Port;
- const TString DefaultAddress;
- const TActorId ReplyTo;
- const TActorId ReplyFrom;
- const TInstant Deadline;
- };
-
- IActor* CreateResolveActor(
- const TString& host, ui16 port, ui32 nodeId, const TString& defaultAddress,
- const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline)
- {
- return new TInterconnectResolveActor(host, port, nodeId, defaultAddress, replyTo, replyFrom, deadline);
- }
-
- IActor* CreateResolveActor(
- const TString& host, ui16 port,
- const TActorId& replyTo, const TActorId& replyFrom, TInstant deadline)
- {
- return new TInterconnectResolveActor(host, port, replyTo, replyFrom, deadline);
- }
-
-} // namespace NActors
diff --git a/library/cpp/actors/interconnect/interconnect_stream.cpp b/library/cpp/actors/interconnect/interconnect_stream.cpp
deleted file mode 100644
index f8db077fa4..0000000000
--- a/library/cpp/actors/interconnect/interconnect_stream.cpp
+++ /dev/null
@@ -1,680 +0,0 @@
-#include "interconnect_stream.h"
-#include "logging.h"
-#include "poller_actor.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 {
- namespace {
- inline int
- LastSocketError() {
-#if defined(_win_)
- return WSAGetLastError();
-#else
- return errno;
-#endif
- }
- }
-
- TSocket::TSocket(SOCKET fd)
- : Descriptor(fd)
- {
- }
-
- TSocket::~TSocket() {
- if (Descriptor == INVALID_SOCKET) {
- return;
- }
-
- auto const result = ::closesocket(Descriptor);
- if (result == 0)
- return;
- switch (LastSocketError()) {
- case EBADF:
- Y_ABORT("Close bad descriptor");
- case EINTR:
- break;
- case EIO:
- Y_ABORT("EIO");
- default:
- Y_ABORT("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);
- if (getsockopt(Descriptor, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&err), &len) == -1) {
- err = LastSocketError();
- }
- return err;
- }
-
- /////////////////////////////////////////////////////////////////
-
- TIntrusivePtr<TStreamSocket> TStreamSocket::Make(int domain, int *error) {
- const SOCKET res = ::socket(domain, SOCK_STREAM | SOCK_NONBLOCK, 0);
- if (res == -1) {
- const int err = LastSocketError();
- Y_ABORT_UNLESS(err != EMFILE && err != ENFILE);
- if (error) {
- *error = err;
- }
- }
- 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);
- 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);
- if (ret < 0)
- return -LastSocketError();
-
- return ret;
- }
-
- ssize_t
- TStreamSocket::WriteV(const struct iovec* iov, int iovcnt) const {
-#ifndef _win_
- const auto ret = ::writev(Descriptor, iov, iovcnt);
- if (ret < 0)
- return -LastSocketError();
- return ret;
-#else
- Y_ABORT("WriteV() unsupported on Windows");
-#endif
- }
-
- ssize_t
- TStreamSocket::ReadV(const struct iovec* iov, int iovcnt) const {
-#ifndef _win_
- const auto ret = ::readv(Descriptor, iov, iovcnt);
- if (ret < 0)
- return -LastSocketError();
- return ret;
-#else
- Y_ABORT("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
- 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;
- }
-
- void TStreamSocket::Request(NActors::TPollerToken& token, bool read, bool write) {
- token.Request(read, write);
- }
-
- bool TStreamSocket::RequestReadNotificationAfterWouldBlock(NActors::TPollerToken& token) {
- return token.RequestReadNotificationAfterWouldBlock();
- }
-
- bool TStreamSocket::RequestWriteNotificationAfterWouldBlock(NActors::TPollerToken& token) {
- return token.RequestWriteNotificationAfterWouldBlock();
- }
-
- size_t TStreamSocket::ExpectedWriteLength() const {
- return 0;
- }
-
- //////////////////////////////////////////////////////
-
- TDatagramSocket::TPtr TDatagramSocket::Make(int domain) {
- const SOCKET res = ::socket(domain, SOCK_DGRAM, 0);
- if (res == -1) {
- const int err = LastSocketError();
- Y_ABORT_UNLESS(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) {
- int ret;
- InitOpenSSL();
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- Ctx.reset(SSL_CTX_new(TLSv1_2_method()));
- Y_ABORT_UNLESS(Ctx, "SSL_CTX_new() failed");
-#else
- Ctx.reset(SSL_CTX_new(TLS_method()));
- Y_ABORT_UNLESS(Ctx, "SSL_CTX_new() failed");
- ret = SSL_CTX_set_min_proto_version(Ctx.get(), TLS1_2_VERSION);
- Y_ABORT_UNLESS(ret == 1, "failed to set min proto version");
- ret = SSL_CTX_set_max_proto_version(Ctx.get(), TLS1_2_VERSION);
- Y_ABORT_UNLESS(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_ABORT_UNLESS(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_ABORT_UNLESS(cert, "failed to parse certificate");
- ret = SSL_CTX_use_certificate(Ctx.get(), cert.get());
- Y_ABORT_UNLESS(ret == 1);
-
- // loading additional certificates in the chain, if any
- while(true) {
- X509 *ca = PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr);
- if (ca == nullptr) {
- break;
- }
- ret = SSL_CTX_add0_chain_cert(Ctx.get(), ca);
- Y_ABORT_UNLESS(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_ABORT_UNLESS(bio);
- std::unique_ptr<RSA, TDeleter> pkey(PEM_read_bio_RSAPrivateKey(bio.get(), nullptr, nullptr, nullptr));
- Y_ABORT_UNLESS(pkey);
- ret = SSL_CTX_use_RSAPrivateKey(Ctx.get(), pkey.get());
- Y_ABORT_UNLESS(ret == 1);
- }
- if (caFilePath) {
- ret = SSL_CTX_load_verify_locations(Ctx.get(), caFilePath.data(), nullptr);
- Y_ABORT_UNLESS(ret == 1);
- }
-
- int success = SSL_CTX_set_cipher_list(Ctx.get(), ciphers ? ciphers.data() : "AES128-GCM-SHA256");
- Y_ABORT_UNLESS(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_ABORT_UNLESS(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_ABORT();
- }
-
- std::optional<std::pair<const void*, size_t>> BlockedSend;
-
- ssize_t Send(const void* msg, size_t len, TString *err) {
- if (BlockedSend && BlockedSend->first == msg && BlockedSend->second < len) {
- len = BlockedSend->second;
- }
- Y_ABORT_UNLESS(!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;
- }
-
- size_t ExpectedWriteLength() const {
- return BlockedSend ? BlockedSend->second : 0;
- }
-
- std::optional<std::pair<void*, size_t>> BlockedReceive;
-
- ssize_t Recv(void* msg, size_t len, TString *err) {
- if (BlockedReceive && BlockedReceive->first == msg && BlockedReceive->second < len) {
- len = BlockedReceive->second;
- }
- Y_ABORT_UNLESS(!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_ABORT("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_ABORT("unsupported on SSL sockets");
- }
-
- ssize_t TSecureSocket::ReadV(const struct iovec* /*iov*/, int /*iovcnt*/) const {
- Y_ABORT("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();
- }
-
- void TSecureSocket::Request(NActors::TPollerToken& token, bool /*read*/, bool /*write*/) {
- token.Request(WantRead(), WantWrite());
- }
-
- bool TSecureSocket::RequestReadNotificationAfterWouldBlock(NActors::TPollerToken& token) {
- bool result = false;
- if (WantRead()) {
- result |= token.RequestReadNotificationAfterWouldBlock();
- }
- if (WantWrite()) {
- result |= token.RequestWriteNotificationAfterWouldBlock();
- }
- return result;
- }
-
- bool TSecureSocket::RequestWriteNotificationAfterWouldBlock(NActors::TPollerToken& token) {
- return RequestReadNotificationAfterWouldBlock(token);
- }
-
- size_t TSecureSocket::ExpectedWriteLength() const {
- return Impl->ExpectedWriteLength();
- }
-}
diff --git a/library/cpp/actors/interconnect/interconnect_stream.h b/library/cpp/actors/interconnect/interconnect_stream.h
deleted file mode 100644
index b9ca804e0e..0000000000
--- a/library/cpp/actors/interconnect/interconnect_stream.h
+++ /dev/null
@@ -1,145 +0,0 @@
-#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 NActors {
- class TPollerToken;
-}
-
-namespace NInterconnect {
- class TSocket: public NActors::TSharedDescriptor, public TNonCopyable {
- protected:
- TSocket(SOCKET fd);
-
- virtual ~TSocket() override;
-
- SOCKET Descriptor;
-
- virtual int GetDescriptor() override;
-
- 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, int *error = nullptr);
-
- 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;
-
- virtual void Request(NActors::TPollerToken& token, bool read, bool write);
- virtual bool RequestReadNotificationAfterWouldBlock(NActors::TPollerToken& token);
- virtual bool RequestWriteNotificationAfterWouldBlock(NActors::TPollerToken& token);
-
- virtual size_t ExpectedWriteLength() 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:
- 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;
- void Request(NActors::TPollerToken& token, bool read, bool write) override;
- bool RequestReadNotificationAfterWouldBlock(NActors::TPollerToken& token) override;
- bool RequestWriteNotificationAfterWouldBlock(NActors::TPollerToken& token) override;
- size_t ExpectedWriteLength() const override;
- };
-
- 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
deleted file mode 100644
index 1409f2cf0c..0000000000
--- a/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp
+++ /dev/null
@@ -1,1139 +0,0 @@
-#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);
-
- void TReceiveContext::TPerChannelContext::PrepareCatchBuffer() {
- size_t bytesToCatch = FetchOffset;
- for (auto it = XdcBuffers.begin(), end = it + FetchIndex; it != end; ++it) {
- bytesToCatch += it->size();
- }
-
- XdcCatchBuffer = TRcBuf::Uninitialized(bytesToCatch);
- XdcCatchBytesRead = 0;
- }
-
- void TReceiveContext::TPerChannelContext::ApplyCatchBuffer() {
- if (auto buffer = std::exchange(XdcCatchBuffer, {})) {
- Y_ABORT_UNLESS(XdcCatchBytesRead >= buffer.size());
-
- const size_t offset = XdcCatchBytesRead % buffer.size();
- const char *begin = buffer.data();
- const char *mid = begin + offset;
- const char *end = begin + buffer.size();
- Y_DEBUG_ABORT_UNLESS(begin <= mid && mid < end);
-
- TRope rope;
- rope.Insert(rope.End(), TRcBuf(TRcBuf::Piece, mid, end, buffer));
- if (begin != mid) {
- rope.Insert(rope.End(), TRcBuf(TRcBuf::Piece, begin, mid, buffer));
- }
-
- DropFront(&rope, buffer.size());
- } else {
- Y_DEBUG_ABORT_UNLESS(!XdcCatchBytesRead);
- }
- }
-
- void TReceiveContext::TPerChannelContext::FetchBuffers(ui16 channel, size_t numBytes,
- std::deque<std::tuple<ui16, TMutableContiguousSpan>>& outQ) {
- Y_DEBUG_ABORT_UNLESS(numBytes);
- auto it = XdcBuffers.begin() + FetchIndex;
- for (;;) {
- Y_DEBUG_ABORT_UNLESS(it != XdcBuffers.end());
- const TMutableContiguousSpan span = it->SubSpan(FetchOffset, numBytes);
- outQ.emplace_back(channel, span);
- numBytes -= span.size();
- FetchOffset += span.size();
- if (FetchOffset == it->size()) {
- ++FetchIndex;
- ++it;
- FetchOffset = 0;
- }
- if (!numBytes) {
- break;
- }
- }
- }
-
- void TReceiveContext::TPerChannelContext::DropFront(TRope *from, size_t numBytes) {
- Y_DEBUG_ABORT_UNLESS(from || !XdcCatchBuffer);
-
- size_t n = numBytes;
- for (auto& pendingEvent : PendingEvents) {
- const size_t numBytesInEvent = Min(n, pendingEvent.XdcSizeLeft);
- pendingEvent.XdcSizeLeft -= numBytesInEvent;
- n -= numBytesInEvent;
- if (!n) {
- break;
- }
- }
-
- while (numBytes) {
- Y_DEBUG_ABORT_UNLESS(!XdcBuffers.empty());
- auto& front = XdcBuffers.front();
- if (from) {
- from->ExtractFrontPlain(front.data(), Min(numBytes, front.size()));
- }
- if (numBytes < front.size()) {
- front = front.SubSpan(numBytes, Max<size_t>());
- if (!FetchIndex) { // we are sending this very buffer, adjust sending offset
- Y_DEBUG_ABORT_UNLESS(numBytes <= FetchOffset);
- FetchOffset -= numBytes;
- }
- break;
- } else {
- numBytes -= front.size();
- Y_DEBUG_ABORT_UNLESS(FetchIndex);
- --FetchIndex;
- XdcBuffers.pop_front();
- }
- }
- }
-
- TInputSessionTCP::TInputSessionTCP(const TActorId& sessionId, TIntrusivePtr<NInterconnect::TStreamSocket> socket,
- TIntrusivePtr<NInterconnect::TStreamSocket> xdcSocket, 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))
- , XdcSocket(std::move(xdcSocket))
- , Context(std::move(context))
- , Common(std::move(common))
- , NodeId(nodeId)
- , Params(std::move(params))
- , ConfirmedByInput(lastConfirmed)
- , Metrics(std::move(metrics))
- , DeadPeerTimeout(deadPeerTimeout)
- {
- Y_ABORT_UNLESS(Context);
- Y_ABORT_UNLESS(Socket);
- Y_ABORT_UNLESS(SessionId);
- Y_ABORT_UNLESS(!Params.UseExternalDataChannel == !XdcSocket);
-
- 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_ABORT_UNLESS(sessions == 1, "sessions# %" PRIu64, ui64(sessions));
-
- // calculate number of bytes to catch
- for (auto& context : Context->ChannelArray) {
- context.PrepareCatchBuffer();
- }
- for (auto& [channel, context] : Context->ChannelMap) {
- context.PrepareCatchBuffer();
- }
-
- UsageHisto.fill(0);
- InputTrafficArray.fill(0);
-
- XXH3_64bits_reset(&XxhashXdcState);
- }
-
- 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::Monotonic();
- TActivationContext::Send(new IEventHandle(EvResumeReceiveData, 0, SelfId(), {}, nullptr, 0));
- }
-
- STATEFN(TInputSessionTCP::WorkingState) {
- std::unique_ptr<IEventBase> termEv;
-
- try {
- WorkingStateImpl(ev);
- } catch (const TExReestablishConnection& ex) {
- LOG_DEBUG_IC_SESSION("ICIS09", "ReestablishConnection, reason# %s", ex.Reason.ToString().data());
- termEv = std::make_unique<TEvSocketDisconnect>(std::move(ex.Reason));
- } catch (const TExDestroySession& ex) {
- LOG_DEBUG_IC_SESSION("ICIS13", "DestroySession, reason# %s", ex.Reason.ToString().data());
- termEv.reset(TInterconnectSessionTCP::NewEvTerminate(std::move(ex.Reason)));
- }
-
- if (termEv) {
- AtomicDecrement(Context->NumInputSessions);
- Send(SessionId, termEv.release());
- PassAway();
- Socket.Reset();
- }
- }
-
- void TInputSessionTCP::CloseInputSession() {
- CloseInputSessionRequested = true;
- ReceiveData();
- }
-
- void TInputSessionTCP::Handle(TEvPollerReady::TPtr ev) {
- auto *msg = ev->Get();
-
- bool useful = false;
- bool writeBlocked = false;
-
- if (msg->Socket == Socket) {
- useful = std::exchange(Context->MainReadPending, false);
- writeBlocked = Context->MainWriteBlocked;
- } else if (msg->Socket == XdcSocket) {
- useful = std::exchange(Context->XdcReadPending, false);
- writeBlocked = Context->XdcWriteBlocked;
- }
-
- if (useful) {
- Metrics->IncUsefulReadWakeups();
- } else if (!ev->Cookie) {
- Metrics->IncSpuriousReadWakeups();
- }
-
- ReceiveData();
-
- if (Params.Encryption && writeBlocked && ev->Sender != SessionId) {
- Send(SessionId, ev->Release().Release());
- }
- }
-
- void TInputSessionTCP::Handle(TEvPollerRegisterResult::TPtr ev) {
- auto *msg = ev->Get();
- if (msg->Socket == Socket) {
- PollerToken = std::move(msg->PollerToken);
- } else if (msg->Socket == XdcSocket) {
- XdcPollerToken = std::move(msg->PollerToken);
- }
- ReceiveData();
- }
-
- void TInputSessionTCP::ReceiveData() {
- TTimeLimit limit(GetMaxCyclesPerEvent());
- ui64 numDataBytes = 0;
-
- LOG_DEBUG_IC_SESSION("ICIS02", "ReceiveData called");
-
- bool enoughCpu = true;
- bool progress = false;
-
- for (;;) {
- if (progress && limit.CheckExceeded()) {
- // we have hit processing time limit for this message, send notification to resume processing a bit later
- TActivationContext::Send(new IEventHandle(EvResumeReceiveData, 0, SelfId(), {}, nullptr, 0));
- enoughCpu = false;
- ++CpuStarvationEvents;
- break;
- }
-
- // clear iteration progress
- progress = false;
-
- // try to process already fetched part from IncomingData
- switch (State) {
- case EState::HEADER:
- if (IncomingData.GetSize() < sizeof(TTcpPacketHeader_v2)) {
- break;
- } else {
- ProcessHeader();
- progress = true;
- continue;
- }
-
- case EState::PAYLOAD:
- Y_DEBUG_ABORT_UNLESS(PayloadSize);
- if (!IncomingData) {
- break;
- } else {
- ProcessPayload(&numDataBytes);
- progress = true;
- continue;
- }
- }
-
- // try to read more data into buffers
- progress |= ReadMore();
- progress |= ReadXdc(&numDataBytes);
-
- if (!progress) { // no progress was made during this iteration
- PreallocateBuffers();
- break;
- }
- }
-
- SetEnoughCpu(enoughCpu);
-
- // 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_ABORT_UNLESS(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_ABORT_UNLESS(UpdateFromInputSession);
- break;
-
- default:
- Y_ABORT("unexpected state");
- }
- break;
- }
- }
-
- for (size_t channel = 0; channel < InputTrafficArray.size(); ++channel) {
- if (auto& value = InputTrafficArray[channel]) {
- Metrics->AddInputChannelsIncomingTraffic(channel, std::exchange(value, 0));
- }
- }
- for (auto& [channel, value] : std::exchange(InputTrafficMap, {})) {
- if (value) {
- Metrics->AddInputChannelsIncomingTraffic(channel, std::exchange(value, 0));
- }
- }
- }
-
- void TInputSessionTCP::ProcessHeader() {
- TTcpPacketHeader_v2 header;
- const bool success = IncomingData.ExtractFrontPlain(&header, sizeof(header));
- Y_ABORT_UNLESS(success);
- PayloadSize = header.PayloadLength;
- const ui64 serial = header.Serial;
- const ui64 confirm = header.Confirm;
- if (!Params.Encryption) {
- ChecksumExpected = std::exchange(header.Checksum, 0);
- if (Params.UseXxhash) {
- XXH3_64bits_reset(&XxhashState);
- XXH3_64bits_update(&XxhashState, &header, sizeof(header));
- if (!PayloadSize) {
- Checksum = XXH3_64bits_digest(&XxhashState);
- }
- } else {
- Checksum = Crc32cExtendMSanCompatible(0, &header, sizeof(header)); // start calculating checksum now
- }
- if (!PayloadSize && Checksum != ChecksumExpected) {
- LOG_ERROR_IC_SESSION("ICIS10", "payload checksum error");
- throw TExReestablishConnection{TDisconnectReason::ChecksumError()};
- }
- }
- if (PayloadSize >= 65536) {
- LOG_CRIT_IC_SESSION("ICIS07", "payload is way too big");
- throw TExDestroySession{TDisconnectReason::FormatError()};
- }
- if (ConfirmedByInput < confirm) {
- ConfirmedByInput = confirm;
- if (AtomicGet(Context->ControlPacketId) <= confirm && !NewPingProtocol) {
- ui64 sendTime = AtomicGet(Context->ControlPacketSendTimer);
- TDuration duration = CyclesToDuration(GetCycleCountFast() - sendTime);
- const auto durationUs = duration.MicroSeconds();
- Metrics->UpdatePingTimeHistogram(durationUs);
- PingQ.push_back(duration);
- if (PingQ.size() > 16) {
- PingQ.pop_front();
- }
- AtomicSet(Context->ControlPacketId, 0ULL);
- }
- }
- if (PayloadSize) {
- const ui64 expectedMin = Context->GetLastPacketSerialToConfirm() + 1;
- const ui64 expectedMax = Context->LastProcessedSerial + 1;
- Y_DEBUG_ABORT_UNLESS(expectedMin <= expectedMax);
- if (CurrentSerial ? serial != CurrentSerial + 1 : (serial == 0 || serial > expectedMin)) {
- LOG_CRIT_IC_SESSION("ICIS06", "%s", TString(TStringBuilder()
- << "packet serial number mismatch"
- << " Serial# " << serial
- << " ExpectedMin# " << expectedMin
- << " ExpectedMax# " << expectedMax
- << " CurrentSerial# " << CurrentSerial
- ).data());
- throw TExDestroySession{TDisconnectReason::FormatError()};
- }
- IgnorePayload = serial != expectedMax;
- CurrentSerial = serial;
- State = EState::PAYLOAD;
- Y_DEBUG_ABORT_UNLESS(!Payload);
- } else if (serial & TTcpPacketBuf::PingRequestMask) {
- Send(SessionId, new TEvProcessPingRequest(serial & ~TTcpPacketBuf::PingRequestMask));
- } else if (serial & TTcpPacketBuf::PingResponseMask) {
- const ui64 sent = serial & ~TTcpPacketBuf::PingResponseMask;
- const ui64 received = GetCycleCountFast();
- HandlePingResponse(CyclesToDuration(received - sent));
- } else if (serial & TTcpPacketBuf::ClockMask) {
- HandleClock(TInstant::MicroSeconds(serial & ~TTcpPacketBuf::ClockMask));
- }
- if (!PayloadSize) {
- ++PacketsReadFromSocket;
- }
- }
-
- 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
- }
- InboundPacketQ.push_back(TInboundPacket{CurrentSerial, 0});
- State = EState::HEADER;
- if (!Params.Encryption) { // see if we are checksumming packet body
- for (const auto&& [data, size] : Payload) {
- if (Params.UseXxhash) {
- XXH3_64bits_update(&XxhashState, data, size);
- } else {
- Checksum = Crc32cExtendMSanCompatible(Checksum, data, size);
- }
- }
- if (Params.UseXxhash) {
- Checksum = XXH3_64bits_digest(&XxhashState);
- }
- if (Checksum != ChecksumExpected) { // validate payload checksum
- LOG_ERROR_IC_SESSION("ICIS04", "payload checksum error");
- throw TExReestablishConnection{TDisconnectReason::ChecksumError()};
- }
- }
- while (Payload) {
- // 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");
- throw TExDestroySession{TDisconnectReason::FormatError()};
- } else if (Payload.GetSize() < part.Size) {
- LOG_CRIT_IC_SESSION("ICIS08", "payload format error ChannelPart# %s", part.ToString().data());
- throw TExDestroySession{TDisconnectReason::FormatError()};
- }
-
- const ui16 channel = part.GetChannel();
- auto& context = GetPerChannelContext(channel);
- auto& pendingEvent = context.PendingEvents.empty() || context.PendingEvents.back().EventData
- ? context.PendingEvents.emplace_back()
- : context.PendingEvents.back();
-
- if (part.IsXdc()) { // external data channel command packet
- XdcCommands.resize(part.Size);
- const bool success = Payload.ExtractFrontPlain(XdcCommands.data(), XdcCommands.size());
- Y_ABORT_UNLESS(success);
- ProcessXdcCommand(channel, context);
- } else if (IgnorePayload) { // throw payload out
- Payload.EraseFront(part.Size);
- } else if (!part.IsLastPart()) { // just ordinary inline event data
- Payload.ExtractFront(part.Size, &pendingEvent.InternalPayload);
- } else { // event final block
- TEventDescr2 v2;
-
- if (part.Size != sizeof(v2)) {
- LOG_CRIT_IC_SESSION("ICIS11", "incorrect last part of an event");
- throw TExDestroySession{TDisconnectReason::FormatError()};
- }
-
- const bool success = Payload.ExtractFrontPlain(&v2, sizeof(v2));
- Y_ABORT_UNLESS(success);
-
- pendingEvent.EventData = TEventData{
- v2.Type,
- v2.Flags,
- v2.Recipient,
- v2.Sender,
- v2.Cookie,
- NWilson::TTraceId(v2.TraceId),
- v2.Checksum,
-#if IC_FORCE_HARDENED_PACKET_CHECKS
- v2.Len
-#endif
- };
-
- Metrics->IncInputChannelsIncomingEvents(channel);
- ProcessEvents(context);
- }
-
- const ui32 traffic = sizeof(part) + part.Size;
- if (channel < InputTrafficArray.size()) {
- InputTrafficArray[channel] += traffic;
- } else {
- InputTrafficMap[channel] += traffic;
- }
- }
-
- // mark packet as processed
- if (IgnorePayload) {
- Y_DEBUG_ABORT_UNLESS(CurrentSerial <= Context->LastProcessedSerial);
- } else {
- ++Context->LastProcessedSerial;
- Y_DEBUG_ABORT_UNLESS(CurrentSerial == Context->LastProcessedSerial);
- }
- XdcCatchStream.Ready = Context->LastProcessedSerial == CurrentSerial;
- ApplyXdcCatchStream();
- ProcessInboundPacketQ(0);
-
- ++PacketsReadFromSocket;
- ++DataPacketsReadFromSocket;
- IgnoredDataPacketsFromSocket += IgnorePayload;
- }
-
- void TInputSessionTCP::ProcessInboundPacketQ(ui64 numXdcBytesRead) {
- for (; !InboundPacketQ.empty(); InboundPacketQ.pop_front()) {
- auto& front = InboundPacketQ.front();
-
- const size_t n = Min(numXdcBytesRead, front.XdcUnreadBytes);
- front.XdcUnreadBytes -= n;
- numXdcBytesRead -= n;
-
- if (front.XdcUnreadBytes) { // we haven't finished this packet yet
- Y_ABORT_UNLESS(!numXdcBytesRead);
- break;
- }
-
- Y_DEBUG_ABORT_UNLESS(front.Serial + InboundPacketQ.size() - 1 <= Context->LastProcessedSerial,
- "front.Serial# %" PRIu64 " LastProcessedSerial# %" PRIu64 " InboundPacketQ.size# %zu",
- front.Serial, Context->LastProcessedSerial, InboundPacketQ.size());
-
- if (Context->GetLastPacketSerialToConfirm() < front.Serial && !Context->AdvanceLastPacketSerialToConfirm(front.Serial)) {
- throw TExReestablishConnection{TDisconnectReason::NewSession()};
- }
- }
- }
-
- void TInputSessionTCP::ProcessXdcCommand(ui16 channel, TReceiveContext::TPerChannelContext& context) {
- const char *ptr = XdcCommands.data();
- const char *end = ptr + XdcCommands.size();
- while (ptr != end) {
- switch (const auto cmd = static_cast<EXdcCommand>(*ptr++)) {
- case EXdcCommand::DECLARE_SECTION:
- case EXdcCommand::DECLARE_SECTION_INLINE: {
- // extract and validate command parameters
- const ui64 headroom = NInterconnect::NDetail::DeserializeNumber(&ptr, end);
- const ui64 size = NInterconnect::NDetail::DeserializeNumber(&ptr, end);
- const ui64 tailroom = NInterconnect::NDetail::DeserializeNumber(&ptr, end);
- const ui64 alignment = NInterconnect::NDetail::DeserializeNumber(&ptr, end);
- if (headroom == Max<ui64>() || size == Max<ui64>() || tailroom == Max<ui64>() || alignment == Max<ui64>()) {
- LOG_CRIT_IC_SESSION("ICIS00", "XDC command format error");
- throw TExDestroySession{TDisconnectReason::FormatError()};
- }
-
- if (!IgnorePayload) { // process command if packet is being applied
- auto& pendingEvent = context.PendingEvents.back();
- const bool isInline = cmd == EXdcCommand::DECLARE_SECTION_INLINE;
- pendingEvent.SerializationInfo.Sections.push_back(TEventSectionInfo{headroom, size, tailroom,
- alignment, isInline});
-
- Y_ABORT_UNLESS(!isInline || Params.UseXdcShuffle);
- if (!isInline) {
- // allocate buffer and push it into the payload
- auto buffer = TRcBuf::Uninitialized(size, headroom, tailroom);
- if (size) {
- context.XdcBuffers.push_back(buffer.GetContiguousSpanMut());
- }
- pendingEvent.ExternalPayload.Insert(pendingEvent.ExternalPayload.End(), TRope(std::move(buffer)));
- pendingEvent.XdcSizeLeft += size;
- ++XdcSections;
- }
- }
- continue;
- }
-
- case EXdcCommand::PUSH_DATA: {
- const size_t cmdLen = sizeof(ui16) + (Params.Encryption ? 0 : sizeof(ui32));
- if (static_cast<size_t>(end - ptr) < cmdLen) {
- LOG_CRIT_IC_SESSION("ICIS18", "XDC command format error");
- throw TExDestroySession{TDisconnectReason::FormatError()};
- }
-
- auto size = *reinterpret_cast<const ui16*>(ptr);
- if (!size) {
- LOG_CRIT_IC_SESSION("ICIS03", "XDC empty payload");
- throw TExDestroySession{TDisconnectReason::FormatError()};
- }
-
- if (!Params.Encryption) {
- const ui32 checksumExpected = *reinterpret_cast<const ui32*>(ptr + sizeof(ui16));
- XdcChecksumQ.emplace_back(size, checksumExpected);
- }
-
- // account channel and number of bytes in XDC for this packet
- auto& packet = InboundPacketQ.back();
- packet.XdcUnreadBytes += size;
-
- if (IgnorePayload) {
- // this packet was already marked as 'processed', all commands had been executed, but we must
- // parse XDC stream from this packet correctly
- const bool apply = Context->GetLastPacketSerialToConfirm() < CurrentSerial &&
- GetPerChannelContext(channel).XdcCatchBuffer;
- XdcCatchStream.BytesPending += size;
- XdcCatchStream.Markup.emplace_back(channel, apply, size);
- } else {
- // find buffers and acquire data buffer pointers
- context.FetchBuffers(channel, size, XdcInputQ);
- }
-
- ptr += cmdLen;
- ++XdcRefs;
- continue;
- }
- }
-
- LOG_CRIT_IC_SESSION("ICIS15", "unexpected XDC command");
- throw TExDestroySession{TDisconnectReason::FormatError()};
- }
- }
-
- void TInputSessionTCP::ProcessEvents(TReceiveContext::TPerChannelContext& context) {
- for (; !context.PendingEvents.empty(); context.PendingEvents.pop_front()) {
- auto& pendingEvent = context.PendingEvents.front();
- if (!pendingEvent.EventData || pendingEvent.XdcSizeLeft) {
- break; // event is not ready yet
- }
- auto& descr = *pendingEvent.EventData;
-
- // create aggregated payload
- TRope payload;
- if (!pendingEvent.SerializationInfo.Sections.empty()) {
- // unshuffle inline and external payloads into single event content
- TRope *prev = nullptr;
- size_t accumSize = 0;
- for (const auto& s : pendingEvent.SerializationInfo.Sections) {
- TRope *rope = s.IsInline
- ? &pendingEvent.InternalPayload
- : &pendingEvent.ExternalPayload;
- if (rope != prev) {
- if (accumSize) {
- prev->ExtractFront(accumSize, &payload);
- }
- prev = rope;
- accumSize = 0;
- }
- accumSize += s.Size;
- }
- if (accumSize) {
- prev->ExtractFront(accumSize, &payload);
- }
-
- if (pendingEvent.InternalPayload || pendingEvent.ExternalPayload) {
- LOG_CRIT_IC_SESSION("ICIS19", "unprocessed payload remains after shuffling"
- " Type# 0x%08" PRIx32 " InternalPayload.size# %zu ExternalPayload.size# %zu",
- descr.Type, pendingEvent.InternalPayload.size(), pendingEvent.ExternalPayload.size());
- Y_DEBUG_ABORT_UNLESS(false);
- throw TExReestablishConnection{TDisconnectReason::FormatError()};
- }
- }
-
- // we add any remains of internal payload to the end
- if (auto& rope = pendingEvent.InternalPayload) {
- rope.ExtractFront(rope.size(), &payload);
- }
- // and ensure there is no unprocessed external payload
- Y_ABORT_UNLESS(!pendingEvent.ExternalPayload);
-
-#if IC_FORCE_HARDENED_PACKET_CHECKS
- if (descr.Len != payload.GetSize()) {
- LOG_CRIT_IC_SESSION("ICIS17", "event length mismatch Type# 0x%08" PRIx32 " received# %zu expected# %" PRIu32,
- descr.Type, payload.GetSize(), descr.Len);
- throw TExReestablishConnection{TDisconnectReason::ChecksumError()};
- }
-#endif
- if (descr.Checksum) {
- ui32 checksum = 0;
- for (const auto&& [data, size] : payload) {
- checksum = Crc32cExtendMSanCompatible(checksum, data, size);
- }
- if (checksum != descr.Checksum) {
- LOG_CRIT_IC_SESSION("ICIS05", "event checksum error Type# 0x%08" PRIx32, descr.Type);
- throw TExReestablishConnection{TDisconnectReason::ChecksumError()};
- }
- }
- pendingEvent.SerializationInfo.IsExtendedFormat = descr.Flags & IEventHandle::FlagExtendedFormat;
- auto ev = std::make_unique<IEventHandle>(SessionId,
- descr.Type,
- descr.Flags & ~IEventHandle::FlagExtendedFormat,
- descr.Recipient,
- descr.Sender,
- MakeIntrusive<TEventSerializedData>(std::move(payload), std::move(pendingEvent.SerializationInfo)),
- descr.Cookie,
- Params.PeerScopeId,
- std::move(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_ABORT_UNLESS(UpdateFromInputSession);
- if (Context->UpdateState.compare_exchange_weak(state, EUpdateState::INFLIGHT)) {
- Send(SessionId, UpdateFromInputSession.Release());
- return;
- }
- }
- }
- }
-
- ssize_t TInputSessionTCP::Read(NInterconnect::TStreamSocket& socket, const TPollerToken::TPtr& token,
- bool *readPending, const TIoVec *iov, size_t num) {
- for (;;) {
- ssize_t recvres = 0;
- TString err;
- LWPROBE_IF_TOO_LONG(SlowICReadFromSocket, ms) {
- do {
- const ui64 begin = GetCycleCountFast();
- if (num == 1) {
- recvres = socket.Recv(iov->Data, iov->Size, &err);
- } else {
- recvres = socket.ReadV(reinterpret_cast<const iovec*>(iov), num);
- }
- const ui64 end = GetCycleCountFast();
- Metrics->IncRecvSyscalls((end - begin) * 1'000'000 / GetCyclesPerMillisecond());
- } while (recvres == -EINTR);
- }
-
- LOG_DEBUG_IC_SESSION("ICIS12", "Read recvres# %zd num# %zu err# %s", recvres, num, 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());
- throw TExReestablishConnection{CloseInputSessionRequested ? TDisconnectReason::Debug() :
- recvres == 0 ? TDisconnectReason::EndOfStream() : TDisconnectReason::FromErrno(-recvres)};
- } else if (token && !*readPending) {
- if (socket.RequestReadNotificationAfterWouldBlock(*token)) {
- continue; // can try again
- } else {
- *readPending = true;
- }
- }
- return -1;
- }
-
- return recvres;
- }
- }
-
- constexpr ui64 GetUsageCountClearMask(size_t items, int bits) {
- ui64 mask = 0;
- for (size_t i = 0; i < items; ++i) {
- mask |= ui64(1 << bits - 2) << i * bits;
- }
- return mask;
- }
-
- bool TInputSessionTCP::ReadMore() {
- PreallocateBuffers();
-
- TStackVec<TIoVec, MaxBuffers> buffs;
- for (auto& item : Buffers) {
- buffs.push_back({item.GetDataMut(), item.size()});
- if (Params.Encryption) {
- break; // do not put more than one buffer in queue to prevent using ReadV
- }
-#ifdef _win_
- break; // do the same thing for Windows build
-#endif
- }
-
- ssize_t recvres = Read(*Socket, PollerToken, &Context->MainReadPending, buffs.data(), buffs.size());
- if (recvres == -1) {
- return false;
- }
-
- Y_ABORT_UNLESS(recvres > 0);
- Metrics->AddTotalBytesRead(recvres);
- BytesReadFromSocket += recvres;
-
- size_t numBuffersCovered = 0;
-
- while (recvres) {
- Y_ABORT_UNLESS(!Buffers.empty());
- auto& buffer = Buffers.front();
- const size_t bytes = Min<size_t>(recvres, buffer.size());
- recvres -= bytes;
- if (const size_t newSize = buffer.size() - bytes) {
- IncomingData.Insert(IncomingData.End(), TRcBuf(TRcBuf::Piece, buffer.data(), bytes, buffer));
- buffer.TrimFront(newSize);
- } else {
- IncomingData.Insert(IncomingData.End(), std::move(buffer));
- Buffers.pop_front();
- }
- ++numBuffersCovered;
- }
-
- if (Buffers.empty()) { // we have read all the data, increase number of buffers
- CurrentBuffers = Min(CurrentBuffers * 2, MaxBuffers);
- } else {
- Y_DEBUG_ABORT_UNLESS(numBuffersCovered);
-
- const size_t index = numBuffersCovered - 1;
-
- static constexpr ui64 itemMask = (1 << BitsPerUsageCount) - 1;
-
- const size_t word = index / ItemsPerUsageCount;
- const size_t offset = index % ItemsPerUsageCount * BitsPerUsageCount;
-
- if ((UsageHisto[word] >> offset & itemMask) == itemMask) { // time to shift
- for (ui64& w : UsageHisto) {
- static constexpr ui64 mask = GetUsageCountClearMask(ItemsPerUsageCount, BitsPerUsageCount);
- w = (w & mask) >> 1;
- }
- }
- UsageHisto[word] += ui64(1) << offset;
-
- while (CurrentBuffers > 1) {
- const size_t index = CurrentBuffers - 1;
- if (UsageHisto[index / ItemsPerUsageCount] >> index % ItemsPerUsageCount * BitsPerUsageCount & itemMask) {
- break;
- } else {
- --CurrentBuffers;
- }
- }
- }
-
- LastReceiveTimestamp = TActivationContext::Monotonic();
-
- return true;
- }
-
- bool TInputSessionTCP::ReadXdcCatchStream(ui64 *numDataBytes) {
- bool progress = false;
-
- while (XdcCatchStream.BytesPending) {
- if (!XdcCatchStream.Buffer) {
- XdcCatchStream.Buffer = TRcBuf::Uninitialized(64 * 1024);
- }
-
- const size_t numBytesToRead = Min<size_t>(XdcCatchStream.BytesPending, XdcCatchStream.Buffer.size());
-
- TIoVec iov{XdcCatchStream.Buffer.GetDataMut(), numBytesToRead};
- ssize_t recvres = Read(*XdcSocket, XdcPollerToken, &Context->XdcReadPending, &iov, 1);
- if (recvres == -1) {
- return progress;
- }
-
- HandleXdcChecksum({XdcCatchStream.Buffer.data(), static_cast<size_t>(recvres)});
-
- XdcCatchStream.BytesPending -= recvres;
- XdcCatchStream.BytesProcessed += recvres;
- *numDataBytes += recvres;
- BytesReadFromXdcSocket += recvres;
-
- // scatter read data
- const char *in = XdcCatchStream.Buffer.data();
- while (recvres) {
- Y_DEBUG_ABORT_UNLESS(!XdcCatchStream.Markup.empty());
- auto& [channel, apply, bytes] = XdcCatchStream.Markup.front();
- size_t bytesInChannel = Min<size_t>(recvres, bytes);
- bytes -= bytesInChannel;
- recvres -= bytesInChannel;
-
- if (apply) {
- auto& context = GetPerChannelContext(channel);
- while (bytesInChannel) {
- const size_t offset = context.XdcCatchBytesRead % context.XdcCatchBuffer.size();
- TMutableContiguousSpan out = context.XdcCatchBuffer.GetContiguousSpanMut().SubSpan(offset, bytesInChannel);
- memcpy(out.data(), in, out.size());
- context.XdcCatchBytesRead += out.size();
- in += out.size();
- bytesInChannel -= out.size();
- }
- } else {
- in += bytesInChannel;
- }
-
- if (!bytes) {
- XdcCatchStream.Markup.pop_front();
- }
- }
-
- progress = true;
- }
-
- ApplyXdcCatchStream();
-
- return progress;
- }
-
- void TInputSessionTCP::ApplyXdcCatchStream() {
- if (!XdcCatchStream.Applied && XdcCatchStream.Ready && !XdcCatchStream.BytesPending) {
- Y_DEBUG_ABORT_UNLESS(XdcCatchStream.Markup.empty());
-
- auto process = [&](auto& context) {
- context.ApplyCatchBuffer();
- ProcessEvents(context);
- };
- for (auto& context : Context->ChannelArray) {
- process(context);
- }
- for (auto& [channel, context] : Context->ChannelMap) {
- process(context);
- }
-
- ProcessInboundPacketQ(XdcCatchStream.BytesProcessed);
-
- XdcCatchStream.Buffer = {};
- XdcCatchStream.Applied = true;
- }
- }
-
- bool TInputSessionTCP::ReadXdc(ui64 *numDataBytes) {
- bool progress = ReadXdcCatchStream(numDataBytes);
-
- // exit if we have no work to do
- if (XdcInputQ.empty() || !XdcCatchStream.Applied) {
- return progress;
- }
-
- TStackVec<TIoVec, 64> buffs;
- size_t size = 0;
- for (auto& [channel, span] : XdcInputQ) {
- buffs.push_back(TIoVec{span.data(), span.size()});
- size += span.size();
- if (buffs.size() == 64 || size >= 1024 * 1024 || Params.Encryption) {
- break;
- }
- }
-
- ssize_t recvres = Read(*XdcSocket, XdcPollerToken, &Context->XdcReadPending, buffs.data(), buffs.size());
- if (recvres == -1) {
- return progress;
- }
-
- // calculate stream checksums
- {
- size_t bytesToChecksum = recvres;
- for (const auto& iov : buffs) {
- const size_t n = Min(bytesToChecksum, iov.Size);
- HandleXdcChecksum({static_cast<const char*>(iov.Data), n});
- bytesToChecksum -= n;
- if (!bytesToChecksum) {
- break;
- }
- }
- }
-
- Y_ABORT_UNLESS(recvres > 0);
- Metrics->AddTotalBytesRead(recvres);
- *numDataBytes += recvres;
- BytesReadFromXdcSocket += recvres;
-
- // cut the XdcInputQ deque
- for (size_t bytesToCut = recvres; bytesToCut; ) {
- Y_ABORT_UNLESS(!XdcInputQ.empty());
- auto& [channel, span] = XdcInputQ.front();
- size_t n = Min(bytesToCut, span.size());
- bytesToCut -= n;
- if (n == span.size()) {
- XdcInputQ.pop_front();
- } else {
- span = span.SubSpan(n, Max<size_t>());
- Y_ABORT_UNLESS(!bytesToCut);
- }
-
- Y_DEBUG_ABORT_UNLESS(n);
- auto& context = GetPerChannelContext(channel);
- context.DropFront(nullptr, n);
- ProcessEvents(context);
- }
-
- // drop fully processed inbound packets
- ProcessInboundPacketQ(recvres);
-
- LastReceiveTimestamp = TActivationContext::Monotonic();
-
- return true;
- }
-
- void TInputSessionTCP::HandleXdcChecksum(TContiguousSpan span) {
- if (Params.Encryption) {
- return;
- }
- while (span.size()) {
- Y_DEBUG_ABORT_UNLESS(!XdcChecksumQ.empty());
- auto& [size, expected] = XdcChecksumQ.front();
- const size_t n = Min<size_t>(size, span.size());
- if (Params.UseXxhash) {
- XXH3_64bits_update(&XxhashXdcState, span.data(), n);
- } else {
- XdcCurrentChecksum = Crc32cExtendMSanCompatible(XdcCurrentChecksum, span.data(), n);
- }
- span = span.SubSpan(n, Max<size_t>());
- size -= n;
- if (!size) {
- if (Params.UseXxhash) {
- XdcCurrentChecksum = XXH3_64bits_digest(&XxhashXdcState);
- XXH3_64bits_reset(&XxhashXdcState);
- }
- if (XdcCurrentChecksum != expected) {
- LOG_ERROR_IC_SESSION("ICIS16", "payload checksum error");
- throw TExReestablishConnection{TDisconnectReason::ChecksumError()};
- }
- XdcChecksumQ.pop_front();
- XdcCurrentChecksum = 0;
- }
- }
- }
-
- void TInputSessionTCP::PreallocateBuffers() {
- // ensure that we have exactly "numBuffers" in queue
- LWPROBE_IF_TOO_LONG(SlowICReadLoopAdjustSize, ms) {
- while (Buffers.size() < CurrentBuffers) {
- Buffers.push_back(TRcBuf::Uninitialized(Common->Settings.PreallocatedBufferSize));
- }
- }
- }
-
- void TInputSessionTCP::PassAway() {
- Metrics->SetClockSkewMicrosec(0);
- TActorBootstrapped::PassAway();
- }
-
- void TInputSessionTCP::HandleCheckDeadPeer() {
- const TMonotonic now = TActivationContext::Monotonic();
- if (now >= LastReceiveTimestamp + DeadPeerTimeout) {
- ReceiveData();
- if (Socket && now >= LastReceiveTimestamp + DeadPeerTimeout) {
- // nothing has changed, terminate session
- throw TExDestroySession{TDisconnectReason::DeadPeer()};
- }
- }
- Schedule(LastReceiveTimestamp + DeadPeerTimeout, 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;
- Metrics->UpdatePingTimeHistogram(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;
- Metrics->SetClockSkewMicrosec(clockSkew);
- }
-
- TReceiveContext::TPerChannelContext& TInputSessionTCP::GetPerChannelContext(ui16 channel) const {
- return channel < std::size(Context->ChannelArray)
- ? Context->ChannelArray[channel]
- : Context->ChannelMap[channel];
- }
-
- void TInputSessionTCP::GenerateHttpInfo(NMon::TEvHttpInfoRes::TPtr ev) {
- TStringStream str;
- ev->Get()->Output(str);
-
- HTML(str) {
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Input Session";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- str << "Sensor";
- }
- TABLEH() {
- str << "Value";
- }
- }
- }
-#define MON_VAR(KEY) \
- TABLER() { \
- TABLED() { str << #KEY; } \
- TABLED() { str << (KEY); } \
- }
-
- TABLEBODY() {
- MON_VAR(BytesReadFromSocket)
- MON_VAR(PacketsReadFromSocket)
- MON_VAR(DataPacketsReadFromSocket)
- MON_VAR(IgnoredDataPacketsFromSocket)
-
- MON_VAR(BytesReadFromXdcSocket)
- MON_VAR(XdcSections)
- MON_VAR(XdcRefs)
- MON_VAR(CpuStarvationEvents)
-
- MON_VAR(PayloadSize)
- MON_VAR(InboundPacketQ.size())
- MON_VAR(XdcInputQ.size())
- MON_VAR(Buffers.size())
- MON_VAR(IncomingData.GetSize())
- MON_VAR(Payload.GetSize())
- MON_VAR(CurrentBuffers)
-
- MON_VAR(Context->LastProcessedSerial)
- MON_VAR(ConfirmedByInput)
- }
- }
- }
- }
- }
-
- TActivationContext::Send(new IEventHandle(ev->Recipient, ev->Sender, new NMon::TEvHttpInfoRes(str.Str())));
- }
-
-}
diff --git a/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp b/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp
deleted file mode 100644
index 514bfb0b84..0000000000
--- a/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp
+++ /dev/null
@@ -1,944 +0,0 @@
-#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 {
- 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))
- {
- Y_ABORT_UNLESS(Common);
- Y_ABORT_UNLESS(Common->NameserviceId);
- if (DynamicPtr) {
- Y_ABORT_UNLESS(!*DynamicPtr);
- *DynamicPtr = this;
- }
- }
-
- void TInterconnectProxyTCP::Bootstrap() {
- SetPrefix(Sprintf("Proxy %s [node %" PRIu32 "]", SelfId().ToString().data(), PeerNodeId));
-
- SwitchToInitialState();
-
- 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);
- mon(path, title, sys, SelfId());
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // PendingActivation
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void TInterconnectProxyTCP::RequestNodeInfo(STATEFN_SIG) {
- ICPROXY_PROFILED;
-
- Y_ABORT_UNLESS(!IncomingHandshakeActor && !OutgoingHandshakeActor && !PendingIncomingHandshakeEvents && !PendingSessionEvents);
- EnqueueSessionEvent(ev);
- StartConfiguring();
- }
-
- void TInterconnectProxyTCP::RequestNodeInfoForIncomingHandshake(STATEFN_SIG) {
- ICPROXY_PROFILED;
-
- if (!Terminated) {
- Y_ABORT_UNLESS(!IncomingHandshakeActor && !OutgoingHandshakeActor && !PendingIncomingHandshakeEvents && !PendingSessionEvents);
- EnqueueIncomingHandshakeEvent(ev);
- StartConfiguring();
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // PendingNodeInfo
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void TInterconnectProxyTCP::StartConfiguring() {
- ICPROXY_PROFILED;
-
- Y_ABORT_UNLESS(!IncomingHandshakeActor && !OutgoingHandshakeActor);
-
- // issue node info request
- 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,
- ConfigureTimeoutCookie = new TEvents::TEvWakeup);
- }
-
- void TInterconnectProxyTCP::Configure(TEvInterconnect::TEvNodeInfo::TPtr& ev) {
- ICPROXY_PROFILED;
-
- Y_ABORT_UNLESS(!IncomingHandshakeActor && !OutgoingHandshakeActor && !Session);
-
- if (!ev->Get()->Node) {
- TransitToErrorState("cannot get node info");
- } else {
- auto& info = *ev->Get()->Node;
- 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;
-
- 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;
-
- // since we are starting initial handshake for some reason, we'll drop any existing handshakes, if any
- 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;
-
- // drop outgoing handshake if we have one; keep incoming handshakes as they may be useful
- DropOutgoingHandshake();
-
- // ensure that we have session
- Y_ABORT_UNLESS(Session);
-
- // ensure that we have both virtual ids
- Y_ABORT_UNLESS(SessionVirtualId);
- Y_ABORT_UNLESS(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;
-
- Y_ABORT_UNLESS(!IncomingHandshakeActor);
- IncomingHandshakeActor = handshakeId;
- IncomingHandshakeActorFilledIn = TActivationContext::Now();
- Y_ABORT_UNLESS(!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_ABORT_UNLESS(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_ABORT_UNLESS(!HeldHandshakeReply);
- 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);
- } else {
- Y_ABORT_UNLESS(CurrentStateFunc() == &TThis::StateWork);
- }
- }
- }
-
- 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",
- 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"
- " 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();
-
- // 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;
-
- 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();
-
- 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);
- return;
- } else {
- RemoteProgramInfo->Serial = remoteSerial;
- }
- } 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"));
- 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
- " LastSerialFromIncomingHandshake# %" PRIu64, ev->Sender.ToString().data(),
- serial, *LastSerialFromIncomingHandshake);
- Send(ev->Sender, new TEvHandshakeReplyError("duplicate serial"));
- return;
- } else if (serial == *LastSerialFromIncomingHandshake) {
- LOG_NOTICE_IC("ICP00", "Handshake# %s is obsolete, serial# %" PRIu64
- " LastSerialFromIncomingHandshake# %" PRIu64, ev->Sender.ToString().data(),
- serial, *LastSerialFromIncomingHandshake);
- Send(ev->Sender, new TEvents::TEvPoisonPill);
- return;
- }
- }
-
- // drop incoming handshake as this is definitely more recent
- DropIncomingHandshake();
-
- // prepare for new session
- 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->SetSerial(virtualId.LocalId());
-
- 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();
- } else if (ev->Sender == OutgoingHandshakeActor) {
- LOG_INFO_IC("ICP20", "outgoing handshake succeeded");
- DropIncomingHandshake();
- DropOutgoingHandshake(false);
- } else {
- /* It seems to be an old handshake. */
- return;
- }
-
- // drop any pending XDC subscriptions
- ConnectionSubscriptions.clear();
-
- Y_ABORT_UNLESS(!IncomingHandshakeActor && !OutgoingHandshakeActor);
- SwitchToState(__LINE__, "StateWork", &TThis::StateWork);
-
- if (Session) {
- // this is continuation request, check that virtual ids match
- Y_ABORT_UNLESS(SessionVirtualId == msg->Self && RemoteSessionVirtualId == msg->Peer);
- } else {
- // this is initial request, check that we have virtual ids not filled in
- Y_ABORT_UNLESS(!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.
- SessionID = RegisterWithSameMailbox(Session = new TInterconnectSessionTCP(this, msg->Params));
- 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_ABORT_UNLESS(Session && SessionVirtualId && RemoteSessionVirtualId);
-
- // Set up new connection for the session.
- 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);
-
- 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);
- } 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);
-
- if (IEventBase* reply = HeldHandshakeReply.Release()) {
- Y_ABORT_UNLESS(IncomingHandshakeActor);
- LOG_DEBUG_IC("ICP26", "sent held handshake reply to %s", IncomingHandshakeActor.ToString().data());
- Send(IncomingHandshakeActor, reply);
- }
-
- // 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");
- return;
- }
-
- if (Metrics) {
- Metrics->IncHandshakeFails();
- }
-
- if (IncomingHandshakeActor || OutgoingHandshakeActor) {
- // one of handshakes is still going on
- 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);
- }
- break;
-
- case TEvHandshakeFail::HANDSHAKE_FAIL_SESSION_MISMATCH:
- StartInitialHandshake();
- break;
-
- case TEvHandshakeFail::HANDSHAKE_FAIL_PERMANENT:
- TString timeExplanation = " LastSessionDieTime# " + LastSessionDieTime.ToString();
- if (Session) {
- 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;
-
- while (PendingSessionEvents) {
- TPendingSessionEvent ev = std::move(PendingSessionEvents.front());
- PendingSessionEventsSize -= ev.Size;
- TAutoPtr<IEventHandle> event(ev.Event.Release());
- PendingSessionEvents.pop_front();
-
- if (Session) {
- ForwardSessionEventToSession(event);
- } else {
- 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(IEventHandle::ForwardOnNondelivery(ev, 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_ABORT("Unexpected type of event in held event queue");
- }
- }
-
- void TInterconnectProxyTCP::UnregisterSession(TInterconnectSessionTCP* session) {
- ICPROXY_PROFILED;
-
- Y_ABORT_UNLESS(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();
-
- // 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::Monotonic() + 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;
-
- Y_ABORT_UNLESS(Session && SessionID);
- ValidateEvent(ev, "ForwardSessionEventToSession");
- InvokeOtherActor(*Session, &TInterconnectSessionTCP::Receive, ev);
- }
-
- 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") {
- str << "Proxy";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- str << "Sensor";
- }
- TABLEH() {
- str << "Value";
- }
- }
- }
-#define MON_VAR(NAME) \
- TABLER() { \
- TABLED() { \
- str << #NAME; \
- } \
- TABLED() { \
- str << NAME; \
- } \
- }
-
- TABLEBODY() {
- MON_VAR(TActivationContext::Now())
- MON_VAR(SessionID)
- MON_VAR(LastSessionDieTime)
- MON_VAR(IncomingHandshakeActor)
- MON_VAR(IncomingHandshakeActorFilledIn)
- MON_VAR(IncomingHandshakeActorReset)
- MON_VAR(OutgoingHandshakeActor)
- MON_VAR(OutgoingHandshakeActorCreated)
- MON_VAR(OutgoingHandshakeActorReset)
- MON_VAR(State)
- MON_VAR(StateSwitchTime)
- }
- }
- }
- }
-
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Error Log";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- str << "Timestamp";
- }
- TABLEH() {
- str << "Elapsed";
- }
- TABLEH() {
- str << "Kind";
- }
- TABLEH() {
- str << "Explanation";
- }
- }
- }
- TABLEBODY() {
- 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) {
- if (std::get<0>(*it) > barrier) {
- str << "<strong>";
- lambda();
- str << "</strong>";
- } else {
- lambda();
- }
- };
- TABLER() {
- TABLED() {
- wrapper([&] {
- str << std::get<0>(*it);
- });
- }
- TABLED() {
- wrapper([&] {
- str << now - std::get<0>(*it);
- });
- }
- TABLED() {
- wrapper([&] {
- str << std::get<1>(*it);
- });
- }
- TABLED() {
- wrapper([&] {
- str << std::get<2>(*it);
- });
-
- ui32 rep = std::get<3>(*it);
- if (rep != 1) {
- str << " <strong>x" << rep << "</strong>";
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- TAutoPtr<IEventHandle> h(new IEventHandle(ev->Sender, ev->Recipient, new NMon::TEvHttpInfoRes(str.Str())));
- if (Session) {
- switch (auto& ev = h; ev->GetTypeRewrite()) {
- hFunc(NMon::TEvHttpInfoRes, Session->GenerateHttpInfo);
- default:
- Y_ABORT();
- }
- } else {
- TActivationContext::Send(h.Release());
- }
- }
-
- 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);
- }
-
- Y_ABORT_UNLESS(Session == nullptr);
- Y_ABORT_UNLESS(!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);
- }
-
- /* Process all pending events. */
- ProcessPendingSessionEvents();
-
- /* Terminate handshakes */
- 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);
- }
- }
- PendingIncomingHandshakeEvents.clear();
- }
-
- void TInterconnectProxyTCP::WakeupFromErrorState(TEvents::TEvWakeup::TPtr& ev) {
- ICPROXY_PROFILED;
-
- LOG_INFO_IC("ICP33", "wake up from error state");
-
- if (ev->Get() == HoldByErrorWakeupCookie) {
- SwitchToInitialState();
- }
- }
-
- void TInterconnectProxyTCP::Disconnect() {
- ICPROXY_PROFILED;
-
- // terminate handshakes (if any)
- DropHandshakes();
-
- if (Session) {
- IActor::InvokeOtherActor(*Session, &TInterconnectSessionTCP::Terminate, TDisconnectReason::UserRequest());
- } else {
- TransitToErrorState("forced disconnect");
- }
- }
-
- void TInterconnectProxyTCP::ScheduleCleanupEventQueue() {
- ICPROXY_PROFILED;
-
- if (!CleanupEventQueueScheduled && PendingSessionEvents) {
- // apply batching at 50 ms granularity
- Schedule(Max(TDuration::MilliSeconds(50), PendingSessionEvents.front().Deadline - TActivationContext::Monotonic()), new TEvCleanupEventQueue);
- CleanupEventQueueScheduled = true;
- }
- }
-
- void TInterconnectProxyTCP::HandleCleanupEventQueue() {
- ICPROXY_PROFILED;
-
- Y_ABORT_UNLESS(CleanupEventQueueScheduled);
- CleanupEventQueueScheduled = false;
- CleanupEventQueue();
- ScheduleCleanupEventQueue();
- }
-
- void TInterconnectProxyTCP::CleanupEventQueue() {
- ICPROXY_PROFILED;
-
- const TMonotonic now = TActivationContext::Monotonic();
- 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");
- Session->Socket->Shutdown(SHUT_RDWR);
- }
- }
-
- void TInterconnectProxyTCP::HandleCloseInputSession() {
- ICPROXY_PROFILED;
-
- if (Session) {
- 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.ExternalDataChannel = Session && Session->XdcSocket;
- 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_ABORT_UNLESS(*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
deleted file mode 100644
index 81f043a2e9..0000000000
--- a/library/cpp/actors/interconnect/interconnect_tcp_proxy.h
+++ /dev/null
@@ -1,570 +0,0 @@
-#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 {
-
-
- /* WARNING: all proxy actors should be alive during actorsystem activity */
- class TInterconnectProxyTCP
- : public TActor<TInterconnectProxyTCP>
- , public TInterconnectLoggingBase
- , public TProfiled
- {
- enum {
- EvCleanupEventQueue = EventSpaceBegin(TEvents::ES_PRIVATE),
- 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;
- bool ExternalDataChannel;
- 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 EActivityType::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);
- }
- }
-
- 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) \
- hFunc(TEvSubscribeForConnection, Handle); \
- hFunc(TEvReportConnection, Handle); \
- default: \
- Y_ABORT("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() {
- ICPROXY_PROFILED;
- }
-
- void Ignore(TEvHandshakeDone::TPtr& ev) {
- ICPROXY_PROFILED;
-
- Y_ABORT_UNLESS(ev->Sender != IncomingHandshakeActor);
- Y_ABORT_UNLESS(ev->Sender != OutgoingHandshakeActor);
- }
-
- void Ignore(TEvHandshakeFail::TPtr& ev) {
- ICPROXY_PROFILED;
-
- Y_ABORT_UNLESS(ev->Sender != IncomingHandshakeActor);
- Y_ABORT_UNLESS(ev->Sender != OutgoingHandshakeActor);
- 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);
- State = name;
- StateSwitchTime = TActivationContext::Now();
- Become(std::forward<TArgs>(args)...);
- Y_ABORT_UNLESS(!Terminated || CurrentStateFunc() == &TThis::HoldByError); // ensure we never escape this state
- if (CurrentStateFunc() != &TThis::PendingActivation) {
- PassAwayTimestamp = TMonotonic::Max();
- } else if (DynamicPtr) {
- PassAwayTimestamp = TActivationContext::Monotonic() + TDuration::Seconds(15);
- if (!PassAwayScheduled) {
- TActivationContext::Schedule(PassAwayTimestamp, new IEventHandle(EvPassAwayIfNeeded, 0, SelfId(),
- {}, nullptr, 0));
- PassAwayScheduled = true;
- }
- }
- }
-
- TMonotonic PassAwayTimestamp;
- bool PassAwayScheduled = false;
-
- void SwitchToInitialState() {
- ICPROXY_PROFILED;
-
- Y_ABORT_UNLESS(!PendingSessionEvents && !PendingIncomingHandshakeEvents, "%s PendingSessionEvents# %zu"
- " PendingIncomingHandshakeEvents# %zu State# %s", LogPrefix.data(), PendingSessionEvents.size(),
- PendingIncomingHandshakeEvents.size(), State);
- SwitchToState(__LINE__, "PendingActivation", &TThis::PendingActivation);
- }
-
- void HandlePassAwayIfNeeded() {
- Y_ABORT_UNLESS(PassAwayScheduled);
- const TMonotonic now = TActivationContext::Monotonic();
- if (now >= PassAwayTimestamp) {
- PassAway();
- } else if (PassAwayTimestamp != TMonotonic::Max()) {
- TActivationContext::Schedule(PassAwayTimestamp, new IEventHandle(EvPassAwayIfNeeded, 0, SelfId(),
- {}, nullptr, 0));
- } else {
- PassAwayScheduled = false;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // PendingActivation
- //
- // In this state we are just waiting for some activities, which may include:
- // * an external Session event
- // * incoming handshake request
- //
- // 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
- Ignore, // Handshake status
- Ignore, // Disconnect request
- Ignore, // Wakeup
- Ignore // Node info
- )
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // PendingNodeInfo
- //
- // This state is entered when we asked nameserver to provide description for peer node we are working with. All
- // external Session events and incoming handshake requests are enqueued into their respective queues, TEvNodeInfo
- // is main event that triggers processing. On success, we try to initiate outgoing handshake if needed, or process
- // incoming handshakes. On error, we enter HoldByError state.
- //
- // 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
- EnqueueIncomingHandshakeEvent, // Handshake status
- Disconnect, // Disconnect request
- ConfigureTimeout, // Wakeup
- Configure // Node info
- )
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // PendingConnection
- //
- // Here we have issued outgoing handshake or have accepted (or may be both) incoming handshake and we are waiting for
- // 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
- HandleHandshakeStatus, // Handshake status
- 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
- HandleHandshakeStatus, // Handshake status
- 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
- Ignore, // Handshake status
- 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_ABORT();
- }
- }
- 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);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // 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();
-
- 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",
- ev->Type, ev->GetTypeRewrite(), ev->Sender.ToString().data());
- LOG_ERROR_IC("ICP03", "%s", msg.data());
- Y_DEBUG_ABORT_UNLESS(false, "%s", msg.data());
- }
-
- Y_ABORT_UNLESS(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
- // All proxy actors share the same information in the object
- // read only
- TInterconnectProxyCommon::TPtr const Common;
-
- const TActorId& GetNameserviceId() const {
- return Common->NameserviceId;
- }
-
- TString TechnicalPeerHostName;
-
- std::shared_ptr<IInterconnectMetrics> Metrics;
-
- void HandleClosePeerSocket();
- void HandleCloseInputSession();
- void HandlePoisonSession();
-
- void HandleSessionBufferSizeRequest(TEvSessionBufferSizeRequest::TPtr& ev);
-
- bool CleanupEventQueueScheduled = false;
- void ScheduleCleanupEventQueue();
- void HandleCleanupEventQueue();
- void CleanupEventQueue();
-
- // hold all events before connection is established
- struct TPendingSessionEvent {
- TMonotonic Deadline;
- ui32 Size;
- THolder<IEventHandle> Event;
-
- TPendingSessionEvent(TMonotonic 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);
- return NActors::TActorId(SelfId().NodeId(), 0, localId, 0);
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- TActorId IncomingHandshakeActor;
- TInstant IncomingHandshakeActorFilledIn;
- TInstant IncomingHandshakeActorReset;
- TMaybe<ui64> LastSerialFromIncomingHandshake;
- THolder<IEventBase> HeldHandshakeReply;
-
- 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);
- }
- LastSerialFromIncomingHandshake.Clear();
- HeldHandshakeReply.Reset();
- IncomingHandshakeActorReset = TActivationContext::Now();
- }
- }
-
- void DropOutgoingHandshake(bool poison = true) {
- ICPROXY_PROFILED;
-
- if (const TActorId& actorId = std::exchange(OutgoingHandshakeActor, TActorId())) {
- LOG_DEBUG_IC("ICP052", "dropped outgoing handshake: %s poison: %s", actorId.ToString().data(),
- poison ? "true" : "false");
- if (poison) {
- Send(actorId, new TEvents::TEvPoisonPill);
- }
- 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());
- }
-
- // ensure we have no current session
- Y_ABORT_UNLESS(!Session);
-
- // switch to pending connection state -- we wait for handshakes, we want more handshakes!
- SwitchToState(__LINE__, "PendingConnection", &TThis::PendingConnection);
- }
-
- void IssueIncomingHandshakeReply(const TActorId& handshakeId, ui64 peerLocalId,
- THolder<IEventBase> event);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- std::unordered_map<TString, TActorId> ConnectionSubscriptions;
-
- void Handle(TEvSubscribeForConnection::TPtr ev) {
- auto& msg = *ev->Get();
- if (msg.Subscribe) {
- if (const auto [it, inserted] = ConnectionSubscriptions.emplace(msg.HandshakeId, ev->Sender); !inserted) {
- Y_DEBUG_ABORT_UNLESS(false);
- ConnectionSubscriptions.erase(it); // collision happened somehow?
- }
- } else {
- ConnectionSubscriptions.erase(msg.HandshakeId);
- }
- }
-
- void Handle(TEvReportConnection::TPtr ev) {
- if (auto nh = ConnectionSubscriptions.extract(ev->Get()->HandshakeId)) {
- TActivationContext::Send(IEventHandle::Forward(ev, nh.mapped()));
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- TActorId OutgoingHandshakeActor;
- TInstant OutgoingHandshakeActorCreated;
- TInstant OutgoingHandshakeActorReset;
-
- TInstant LastSessionDieTime;
-
- 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)));
- }
-
- TDeque<THolder<IEventHandle>> PendingIncomingHandshakeEvents;
-
- 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);
- if (ErrorStateLog.size() > 20) {
- ErrorStateLog.pop_front();
- }
- }
-
- 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
deleted file mode 100644
index df0c172dc1..0000000000
--- a/library/cpp/actors/interconnect/interconnect_tcp_server.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-#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 {
- TInterconnectListenerTCP::TInterconnectListenerTCP(const TString& address, ui16 port, TInterconnectProxyCommon::TPtr common, const TMaybe<SOCKET>& socket)
- : TActor(&TThis::Initial)
- , TInterconnectLoggingBase(Sprintf("ICListener: %s", SelfId().ToString().data()))
- , Address(address)
- , Port(port)
- , Listener(
- socket
- ? new NInterconnect::TStreamSocket(*socket)
- : nullptr)
- , ExternalSocket(!!Listener)
- , ProxyCommonCtx(std::move(common))
- {
- if (ExternalSocket) {
- 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");
- TActor::Die(ctx);
- }
-
- int TInterconnectListenerTCP::Bind() {
- auto doTry = [&](NInterconnect::TAddress addr) {
- int error;
- Listener = NInterconnect::TStreamSocket::Make(addr.GetFamily(), &error);
- if (*Listener == -1) {
- return error;
- }
- SetNonBlock(*Listener);
- Listener->SetSendBufferSize(ProxyCommonCtx->Settings.GetSendBufferSize()); // TODO(alexvru): WTF?
- SetSockOpt(*Listener, SOL_SOCKET, SO_REUSEADDR, 1);
- if (addr.GetFamily() == AF_INET6) {
- SetSockOpt(*Listener, IPPROTO_IPV6, IPV6_V6ONLY, 0);
- }
- const ui32 backlog = ProxyCommonCtx->Settings.SocketBacklogSize;
- if (const auto e = -Listener->Bind(addr)) {
- return e;
- } else if (const auto e = -Listener->Listen(backlog ? backlog : SOMAXCONN)) {
- return e;
- } else {
- return 0;
- }
- };
-
- if (Address) {
- NInterconnect::TAddress addr(Address, Port);
- if (ProxyCommonCtx->Settings.BindOnAllAddresses) {
- addr = addr.GetFamily() == AF_INET ? NInterconnect::TAddress::AnyIPv4(Port) :
- addr.GetFamily() == AF_INET6 ? NInterconnect::TAddress::AnyIPv6(Port) : addr;
- }
- return doTry(addr);
- } else {
- int error = doTry(NInterconnect::TAddress::AnyIPv6(Port));
- if (error == EAFNOSUPPORT || error == EPROTONOSUPPORT) {
- error = doTry(NInterconnect::TAddress::AnyIPv4(Port));
- }
- return error;
- }
- }
-
- void TInterconnectListenerTCP::Bootstrap(const TActorContext& ctx) {
- if (!Listener) {
- if (const int err = Bind()) {
- LOG_ERROR_IC("ICL01", "Bind failed: %s (%s:%u)", strerror(err), Address.data(), Port);
- Listener.Reset();
- Become(&TThis::Initial, TDuration::Seconds(1), new TEvents::TEvBootstrap);
- return;
- }
- }
- if (const auto& callback = ProxyCommonCtx->InitWhiteboard) {
- callback(Port, TlsActivationContext->ExecutorThread.ActorSystem);
- }
- const bool success = ctx.Send(MakePollerActorId(), new TEvPollerRegister(Listener, SelfId(), {}));
- Y_ABORT_UNLESS(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_ABORT_UNLESS(-r != ENFILE && -r != EMFILE && !ExternalSocket);
- LOG_ERROR_IC("ICL06", "Listen failed: %s (%s:%u)", strerror(-r), Address.data(), Port);
- Listener.Reset();
- PollerToken.Reset();
- Become(&TThis::Initial, TDuration::Seconds(1), new TEvents::TEvBootstrap);
- } else if (PollerToken && PollerToken->RequestReadNotificationAfterWouldBlock()) {
- continue;
- }
- break;
- }
- }
-
-}
diff --git a/library/cpp/actors/interconnect/interconnect_tcp_server.h b/library/cpp/actors/interconnect/interconnect_tcp_server.h
deleted file mode 100644
index 41f46ab6d4..0000000000
--- a/library/cpp/actors/interconnect/interconnect_tcp_server.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#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 {
- class TInterconnectListenerTCP: public TActor<TInterconnectListenerTCP>, public TInterconnectLoggingBase {
- public:
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::INTERCONNECT_COMMON;
- }
-
- TInterconnectListenerTCP(const TString& address, ui16 port, TInterconnectProxyCommon::TPtr common, const TMaybe<SOCKET>& socket = Nothing());
- 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);
- }
- }
-
- 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);
-
- const TString Address;
- const ui16 Port;
- TIntrusivePtr<NInterconnect::TStreamSocket> Listener;
- const bool ExternalSocket;
- 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'};
- 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
deleted file mode 100644
index 7d6f8d012f..0000000000
--- a/library/cpp/actors/interconnect/interconnect_tcp_session.cpp
+++ /dev/null
@@ -1,1322 +0,0 @@
-#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 {
- LWTRACE_USING(ACTORLIB_PROVIDER);
-
- 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)...);
- }
- }
-
- TInterconnectSessionTCP::TInterconnectSessionTCP(TInterconnectProxyTCP* const proxy, TSessionParams params)
- : TActor(&TInterconnectSessionTCP::StateFunc)
- , Created(TInstant::Now())
- , Proxy(proxy)
- , CloseOnIdleWatchdog(GetCloseOnIdleTimeout(), std::bind(&TThis::OnCloseOnIdleTimerHit, this))
- , LostConnectionWatchdog(GetLostConnectionTimeout(), std::bind(&TThis::OnLostConnectionTimerHit, this))
- , Params(std::move(params))
- , TotalOutputQueueSize(0)
- , OutputStuckFlag(false)
- , OutputQueueUtilization(16)
- , OutputCounter(0ULL)
- {
- 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);
- }
- if (XdcSocket) {
- XdcSocket->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);
- SetPrefix(Sprintf("Session %s [node %" PRIu32 "]", SelfId().ToString().data(), Proxy->PeerNodeId));
- 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 " reason# %s", (Socket ? i64(*Socket) : -1), reason.ToString().data());
-
- 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);
-
- Proxy->Metrics->SubOutputBuffersTotalSize(TotalOutputQueueSize);
- Proxy->Metrics->SubInflightDataAmount(InflightDataAmount);
-
- LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] session destroyed", Proxy->PeerNodeId);
-
- if (!Subscribers.empty()) {
- Proxy->Metrics->SubSubscribersCount(Subscribers.size());
- }
-
- TActor::PassAway();
- }
-
- void TInterconnectSessionTCP::PassAway() {
- Y_ABORT("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);
- }
-
- ui16 evChannel = ev->GetChannel();
- 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);
-
- TotalOutputQueueSize += dataSize;
- Proxy->Metrics->AddOutputBuffersTotalSize(dataSize);
- if (!wasWorking) {
- // 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);
- ++NumEventsInQueue;
- RearmCloseOnIdle();
-
- LWTRACK(EnqueueEvent, event->Orbit, Proxy->PeerNodeId, NumEventsInQueue, GetWriteBlockedTotal(), evChannel, oChannel.GetQueueSize(), oChannel.GetBufferedAmountOfData());
-
- // check for overloaded queues
- 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,
- Socket ? i64(*Socket) : -1, TotalOutputQueueSize, sendBufferDieLimit);
- return Terminate(TDisconnectReason::QueueOverload());
- }
-
- 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);
- }
- }
-
- IssueRam(true);
- }
-
- 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) {
- Proxy->Metrics->IncSubscribersCount();
- } else {
- it->second = ev->Cookie;
- }
- Send(ev->Sender, new TEvInterconnect::TEvNodeConnected(Proxy->PeerNodeId), 0, ev->Cookie);
- }
-
- 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();
-
- // close existing input session, if any, and do nothing upon its destruction
- ReestablishConnection({}, false, TDisconnectReason::NewSession());
- const ui64 lastInputSerial = ReceiveContext->LockLastPacketSerialToConfirm();
-
- 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) {
- if (ReceiverId) {
- // upon destruction of input session actor invoke this callback again
- 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();
- BytesWrittenToSocket = 0;
-
- SendBufferSize = ev->Get()->Socket->GetSendBufferSize();
- Socket = std::move(ev->Get()->Socket);
- XdcSocket = std::move(ev->Get()->XdcSocket);
-
- // there may be a race
- const ui64 nextPacket = Max(LastConfirmed, ev->Get()->NextPacket);
-
- // arm watchdogs
- RearmCloseOnIdle();
-
- // reset activity timestamps
- LastInputActivityTimestamp = LastPayloadActivityTimestamp = TActivationContext::Monotonic();
-
- LOG_INFO_IC_SESSION("ICS10", "traffic start");
-
- // reset parameters to initial values
- WriteBlockedByFullSendBuffer = false;
- ReceiveContext->MainWriteBlocked = false;
- ReceiveContext->XdcWriteBlocked = false;
- ReceiveContext->MainReadPending = false;
- ReceiveContext->XdcReadPending = false;
-
- // create input session actor
- ReceiveContext->UnlockLastPacketSerialToConfirm();
- auto actor = MakeHolder<TInputSessionTCP>(SelfId(), Socket, XdcSocket, ReceiveContext, Proxy->Common,
- Proxy->Metrics, Proxy->PeerNodeId, nextPacket, GetDeadPeerTimeout(), Params);
- ReceiverId = RegisterWithSameMailbox(actor.Release());
-
- // 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_ABORT_UNLESS(success);
- if (XdcSocket) {
- const bool success = Send(MakePollerActorId(), new TEvPollerRegister(XdcSocket, ReceiverId, SelfId()));
- Y_ABORT_UNLESS(success);
- }
-
- LostConnectionWatchdog.Disarm();
- Proxy->Metrics->SetConnected(1);
- LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] connected", Proxy->PeerNodeId);
-
- // arm pinger timer
- 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 send queue
-
- // drop confirmed packets first as we do not need unwanted retransmissions
- OutgoingStream.RewindToEnd();
- XdcStream.RewindToEnd();
- XdcOffset = Max<size_t>();
- OutgoingOffset = 0;
- OutgoingIndex = SendQueue.size();
- DropConfirmed(nextPacket);
- OutgoingStream.Rewind();
- OutOfBandStream = {};
- XdcStream.Rewind();
- OutgoingOffset = XdcOffset = 0;
- OutgoingIndex = 0;
- ForcedWriteLength = 0;
-
- const ui64 serial = OutputCounter - SendQueue.size() + 1;
- Y_ABORT_UNLESS(serial > LastConfirmed, "%s serial# %" PRIu64 " LastConfirmed# %" PRIu64, LogPrefix.data(), serial, LastConfirmed);
- LOG_DEBUG_IC_SESSION("ICS06", "rewind SendQueue size# %zu LastConfirmed# %" PRIu64 " NextSerial# %" PRIu64,
- SendQueue.size(), LastConfirmed, serial);
-
- SwitchStuckPeriod();
-
- LastHandshakeDone = TActivationContext::Now();
-
- GenerateTraffic();
- }
-
- void TInterconnectSessionTCP::Handle(TEvUpdateFromInputSession::TPtr& ev) {
- if (ev->Sender == ReceiverId) {
- TEvUpdateFromInputSession& msg = *ev->Get();
-
- // update ping time
- Ping = msg.Ping;
- LWPROBE(UpdateFromInputSession, Proxy->PeerNodeId, Ping.MillisecondsFloat());
-
- bool needConfirm = false;
-
- // update activity timer for dead peer checker
- LastInputActivityTimestamp = TActivationContext::Monotonic();
-
- if (msg.NumDataBytes) {
- UnconfirmedBytes += msg.NumDataBytes;
- if (UnconfirmedBytes >= GetTotalInflightAmountOfData() / 4) {
- needConfirm = true;
- } else {
- SetForcePacketTimestamp(Proxy->Common->Settings.ForceConfirmPeriod);
- }
-
- // reset payload watchdog that controls close-on-idle behaviour
- LastPayloadActivityTimestamp = TActivationContext::Monotonic();
- RearmCloseOnIdle();
- }
-
- LWPROBE_IF_TOO_LONG(SlowICDropConfirmed, Proxy->PeerNodeId, ms) {
- DropConfirmed(msg.ConfirmedByInput);
- }
-
- // if we haven't generated any packets, then make a lone Flush packet without any data
- if (needConfirm && Socket) {
- ++ConfirmPacketsForcedBySize;
- MakePacket(false);
- }
-
- GenerateTraffic();
-
- for (;;) {
- switch (EUpdateState state = ReceiveContext->UpdateState) {
- case EUpdateState::NONE:
- case EUpdateState::CONFIRMING:
- Y_ABORT("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::IssueRam(bool batching) {
- const auto& batchPeriod = Proxy->Common->Settings.BatchPeriod;
- if (!RamInQueue || (!batching && RamInQueue->Batching && batchPeriod != TDuration())) {
- auto ev = std::make_unique<TEvRam>(batching);
- RamInQueue = ev.get();
- auto handle = std::make_unique<IEventHandle>(SelfId(), SelfId(), ev.release());
- if (batching && batchPeriod != TDuration()) {
- TActivationContext::Schedule(batchPeriod, handle.release());
- } else {
- TActivationContext::Send(handle.release());
- }
- LWPROBE(StartRam, Proxy->PeerNodeId);
- RamStartedCycles = GetCycleCountFast();
- }
- }
-
- 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() {
- if (!TimeLimit) {
- TimeLimit.emplace(GetMaxCyclesPerEvent());
- }
-
- // generate ping request, if needed
- IssuePingRequest();
-
- while (Socket) {
- ProducePackets();
- if (!Socket) {
- return;
- }
-
- WriteData();
- if (!Socket) {
- return;
- }
-
- bool canProducePackets;
- bool canWriteData;
-
- canProducePackets = NumEventsInQueue && InflightDataAmount < GetTotalInflightAmountOfData() &&
- GetUnsentSize() < GetUnsentLimit();
-
- canWriteData = ((OutgoingStream || OutOfBandStream) && !ReceiveContext->MainWriteBlocked) ||
- (XdcStream && !ReceiveContext->XdcWriteBlocked);
-
- if (!canProducePackets && !canWriteData) {
- SetEnoughCpu(true); // we do not starve
- break;
- } else if (TimeLimit->CheckExceeded()) {
- SetEnoughCpu(false);
- IssueRam(false);
- break;
- }
- }
-
- // account traffic changes
- ChannelScheduler->ForEach([](TEventOutputChannel& channel) {
- channel.AccountTraffic();
- });
-
- // equalize channel weights
- EqualizeCounter += ChannelScheduler->Equalize();
- }
-
- void TInterconnectSessionTCP::ProducePackets() {
- // 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
- static constexpr ui32 maxBytesToProduce = 64 * 1024;
- ui32 bytesProduced = 0;
- while (NumEventsInQueue && InflightDataAmount < GetTotalInflightAmountOfData() && GetUnsentSize() < GetUnsentLimit()) {
- if ((bytesProduced && TimeLimit->CheckExceeded()) || bytesProduced >= maxBytesToProduce) {
- break;
- }
- try {
- bytesProduced += MakePacket(true);
- } catch (const TExSerializedEventTooLarge& ex) {
- // terminate session if the event can't be serialized properly
- LOG_CRIT_IC("ICS31", "serialized event Type# 0x%08" PRIx32 " is too large", ex.Type);
- return Terminate(TDisconnectReason::EventTooLarge());
- }
- }
- }
-
- void TInterconnectSessionTCP::StartHandshake() {
- LOG_INFO_IC_SESSION("ICS15", "start handshake");
- IActor::InvokeOtherActor(*Proxy, &TInterconnectProxyTCP::StartResumeHandshake, ReceiveContext->LockLastPacketSerialToConfirm());
- }
-
- void TInterconnectSessionTCP::ReestablishConnectionWithHandshake(TDisconnectReason reason) {
- ReestablishConnection({}, true, std::move(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;
- if (!ReceiverId) {
- ReestablishConnectionExecute();
- }
- }
- }
-
- void TInterconnectSessionTCP::OnDisconnect(TEvSocketDisconnect::TPtr& ev) {
- if (ev->Sender == ReceiverId) {
- if (ev->Get()->Reason == TDisconnectReason::EndOfStream() && !NumEventsInQueue && OutputCounter == LastConfirmed) {
- return Terminate(ev->Get()->Reason);
- }
-
- const bool wasConnected(Socket);
- 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();
- } else {
- ReestablishConnectionExecute();
- }
- }
- }
-
- void TInterconnectSessionTCP::ShutdownSocket(TDisconnectReason reason) {
- if (Socket) {
- 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());
- Socket->Shutdown(SHUT_RDWR);
- Socket.Reset();
- Proxy->Metrics->IncDisconnections();
- CloseOnIdleWatchdog.Disarm();
- LostConnectionWatchdog.Rearm(SelfId());
- Proxy->Metrics->SetConnected(0);
- LOG_INFO(*TlsActivationContext, NActorsServices::INTERCONNECT_STATUS, "[%u] disconnected", Proxy->PeerNodeId);
- }
- if (XdcSocket) {
- XdcSocket->Shutdown(SHUT_RDWR);
- XdcSocket.Reset();
- }
- }
-
- 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",
- WriteBlockedByFullSendBuffer ? "true" : "false");
-
- auto *msg = ev->Get();
- bool useful = false;
- bool readPending = false;
-
- if (msg->Socket == Socket) {
- useful = std::exchange(ReceiveContext->MainWriteBlocked, false);
- readPending = ReceiveContext->MainReadPending;
- } else if (msg->Socket == XdcSocket) {
- useful = std::exchange(ReceiveContext->XdcWriteBlocked, false);
- readPending = ReceiveContext->XdcReadPending;
- }
-
- if (useful) {
- Proxy->Metrics->IncUsefulWriteWakeups();
- } else if (!ev->Cookie) {
- Proxy->Metrics->IncSpuriousWriteWakeups();
- }
-
- if (Params.Encryption && readPending && ev->Sender != ReceiverId) {
- Send(ReceiverId, ev->Release().Release());
- }
-
- GenerateTraffic();
- }
-
- void TInterconnectSessionTCP::Handle(TEvPollerRegisterResult::TPtr ev) {
- auto *msg = ev->Get();
- bool sendPollerReady = false;
-
- if (msg->Socket == Socket) {
- PollerToken = std::move(msg->PollerToken);
- sendPollerReady = ReceiveContext->MainWriteBlocked;
- } else if (msg->Socket == XdcSocket) {
- XdcPollerToken = std::move(msg->PollerToken);
- sendPollerReady = ReceiveContext->XdcWriteBlocked;
- }
-
- if (sendPollerReady) {
- Send(SelfId(), new TEvPollerReady(msg->Socket, false, true));
- }
- }
-
- void TInterconnectSessionTCP::WriteData() {
- // total bytes written during this call
- ui64 written = 0;
-
- auto process = [&](NInterconnect::TOutgoingStream& stream, const TIntrusivePtr<NInterconnect::TStreamSocket>& socket,
- const TPollerToken::TPtr& token, bool *writeBlocked, size_t maxBytes) {
- size_t totalWritten = 0;
-
- if (stream && socket && !*writeBlocked) {
- for (;;) {
- if (const ssize_t r = Write(stream, *socket, maxBytes); r > 0) {
- stream.Advance(r);
- totalWritten += r;
- } else if (r == -1) {
- if (token && socket->RequestWriteNotificationAfterWouldBlock(*token)) {
- continue; // we can try again
- }
- *writeBlocked = true;
- } else if (r == 0) {
- // error condition
- } else {
- Y_UNREACHABLE();
- }
- break;
- }
- }
-
- written += totalWritten;
- return totalWritten;
- };
-
- auto sendQueueIt = SendQueue.begin() + OutgoingIndex;
- static constexpr size_t maxBytesAtOnce = 256 * 1024;
- size_t bytesToSendInMain = maxBytesAtOnce;
-
- Y_DEBUG_ABORT_UNLESS(OutgoingIndex < SendQueue.size() || (OutgoingIndex == SendQueue.size() && !OutgoingOffset && !OutgoingStream));
-
- if (OutOfBandStream) {
- bytesToSendInMain = 0;
-
- if (!ForcedWriteLength && OutgoingOffset) {
- ForcedWriteLength = 1; // send at least one byte from current packet
- }
-
- // align send up to packet boundary
- size_t offset = OutgoingOffset;
- for (auto it = sendQueueIt; ForcedWriteLength; ++it, offset = 0) {
- Y_DEBUG_ABORT_UNLESS(it != SendQueue.end());
- bytesToSendInMain += it->PacketSize - offset; // send remainder of current packet
- ForcedWriteLength -= Min(it->PacketSize - offset, ForcedWriteLength);
- }
- }
-
- if (bytesToSendInMain) {
- const size_t w = process(OutgoingStream, Socket, PollerToken, &ReceiveContext->MainWriteBlocked, bytesToSendInMain);
-
- // adjust sending queue iterator
- for (OutgoingOffset += w; OutgoingOffset && sendQueueIt->PacketSize <= OutgoingOffset; ++sendQueueIt, ++OutgoingIndex) {
- OutgoingOffset -= sendQueueIt->PacketSize;
- }
-
- BytesWrittenToSocket += w;
-
- if (OutOfBandStream) {
- BytesAlignedForOutOfBand += w;
- bytesToSendInMain -= w;
- }
-
- ForcedWriteLength = Socket ? Socket->ExpectedWriteLength() : 0;
- }
-
- if (!bytesToSendInMain && !ForcedWriteLength) {
- if (const size_t w = process(OutOfBandStream, Socket, PollerToken, &ReceiveContext->MainWriteBlocked, maxBytesAtOnce)) {
- OutOfBandStream.DropFront(w);
- BytesWrittenToSocket += w;
- OutOfBandBytesSent += w;
- }
- }
-
- if (const size_t w = process(XdcStream, XdcSocket, XdcPollerToken, &ReceiveContext->XdcWriteBlocked, maxBytesAtOnce)) {
- XdcBytesSent += w;
- XdcOffset += w;
- }
-
- if (written) {
- Proxy->Metrics->AddTotalBytesWritten(written);
- }
-
- DropConfirmed(LastConfirmed);
-
- const bool writeBlockedByFullSendBuffer = ReceiveContext->MainWriteBlocked || ReceiveContext->XdcWriteBlocked;
- if (WriteBlockedByFullSendBuffer < writeBlockedByFullSendBuffer) { // became blocked
- WriteBlockedCycles = GetCycleCountFast();
- LOG_DEBUG_IC_SESSION("ICS18", "hit send buffer limit");
- } else if (writeBlockedByFullSendBuffer < WriteBlockedByFullSendBuffer) { // became unblocked
- WriteBlockedTotal += TDuration::Seconds(NHPTimer::GetSeconds(GetCycleCountFast() - WriteBlockedCycles));
- }
- WriteBlockedByFullSendBuffer = writeBlockedByFullSendBuffer;
- }
-
- ssize_t TInterconnectSessionTCP::Write(NInterconnect::TOutgoingStream& stream, NInterconnect::TStreamSocket& socket,
- size_t maxBytes) {
- LWPROBE_IF_TOO_LONG(SlowICWriteData, Proxy->PeerNodeId, ms) {
- constexpr ui32 iovLimit = 256;
-
- ui32 maxElementsInIOV;
- if (Params.Encryption) {
- maxElementsInIOV = 1;
- } else {
-#if defined(_win_)
- maxElementsInIOV = 1;
-#elif defined(_linux_)
- maxElementsInIOV = Min<ui32>(iovLimit, sysconf(_SC_IOV_MAX));
-#else
- maxElementsInIOV = 64;
-#endif
- }
-
- TStackVec<TConstIoVec, iovLimit> wbuffers;
-
- stream.ProduceIoVec(wbuffers, maxElementsInIOV, maxBytes);
- Y_ABORT_UNLESS(!wbuffers.empty());
-
- TString err;
- ssize_t r = 0;
- { // issue syscall with timing
- const ui64 begin = GetCycleCountFast();
-
- do {
- if (wbuffers.size() == 1) {
- auto& front = wbuffers.front();
- r = socket.Send(front.Data, front.Size, &err);
- } else {
- r = socket.WriteV(reinterpret_cast<const iovec*>(wbuffers.data()), wbuffers.size());
- }
- } while (r == -EINTR);
-
- const ui64 end = GetCycleCountFast();
- Proxy->Metrics->IncSendSyscalls((end - begin) * 1'000'000 / GetCyclesPerMillisecond());
- }
-
- if (r > 0) {
- return 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 (r == 0 && !NumEventsInQueue && LastConfirmed == OutputCounter) {
- Terminate(TDisconnectReason::EndOfStream());
- } else {
- ReestablishConnectionWithHandshake(r == 0 ? TDisconnectReason::EndOfStream() : TDisconnectReason::FromErrno(-r));
- }
- return 0; // error indicator
- } else {
- return -1; // temporary error
- }
- }
-
- Y_UNREACHABLE();
- }
-
- void TInterconnectSessionTCP::SetForcePacketTimestamp(TDuration period) {
- if (period != TDuration::Max()) {
- // randomize period a bit
- period = TDuration::FromValue(period.GetValue() - RandomNumber<ui64>(period.GetValue() / 10));
- const TMonotonic when = TActivationContext::Monotonic() + period;
- if (when < ForcePacketTimestamp) {
- ForcePacketTimestamp = when;
- ScheduleFlush();
- }
- }
- }
-
- void TInterconnectSessionTCP::ScheduleFlush() {
- if (FlushSchedule.empty() || ForcePacketTimestamp < FlushSchedule.top()) {
- Schedule(ForcePacketTimestamp, new TEvFlush);
- FlushSchedule.push(ForcePacketTimestamp);
- MaxFlushSchedule = Max(MaxFlushSchedule, FlushSchedule.size());
- ++FlushEventsScheduled;
- }
- }
-
- void TInterconnectSessionTCP::HandleFlush() {
- const TMonotonic now = TActivationContext::Monotonic();
- while (FlushSchedule && now >= FlushSchedule.top()) {
- FlushSchedule.pop();
- }
- if (Socket) {
- if (now >= ForcePacketTimestamp) {
- ++ConfirmPacketsForcedByTimeout;
- ++FlushEventsProcessed;
- MakePacket(false); // just generate confirmation packet if we have preconditions for this
- } else if (ForcePacketTimestamp != TMonotonic::Max()) {
- ScheduleFlush();
- }
- GenerateTraffic();
- }
- }
-
- void TInterconnectSessionTCP::ResetFlushLogic() {
- ForcePacketTimestamp = TMonotonic::Max();
- UnconfirmedBytes = 0;
- const TDuration ping = Proxy->Common->Settings.PingPeriod;
- if (ping != TDuration::Zero() && !NumEventsInQueue) {
- SetForcePacketTimestamp(ping);
- }
- }
-
- ui32 TInterconnectSessionTCP::MakePacket(bool data, TMaybe<ui64> pingMask) {
- NInterconnect::TOutgoingStream& stream = data ? OutgoingStream : OutOfBandStream;
-
-#ifndef NDEBUG
- const size_t outgoingStreamSizeBefore = stream.CalculateOutgoingSize();
- const size_t xdcStreamSizeBefore = XdcStream.CalculateOutgoingSize();
-#endif
-
- stream.Align();
- XdcStream.Align();
-
- TTcpPacketOutTask packet(Params, stream, XdcStream);
- ui64 serial = 0;
-
- if (data) {
- // generate serial for this data packet
- serial = ++OutputCounter;
-
- // fill the data packet
- Y_ABORT_UNLESS(NumEventsInQueue);
- LWPROBE_IF_TOO_LONG(SlowICFillSendingBuffer, Proxy->PeerNodeId, ms) {
- FillSendingBuffer(packet, serial);
- }
- Y_ABORT_UNLESS(!packet.IsEmpty());
-
- InflightDataAmount += packet.GetDataSize();
- Proxy->Metrics->AddInflightDataAmount(packet.GetDataSize());
- 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::Monotonic();
- } else if (pingMask) {
- serial = *pingMask;
- }
-
- const ui64 lastInputSerial = ReceiveContext->GetLastPacketSerialToConfirm();
-
- packet.Finish(serial, lastInputSerial);
-
- // count number of bytes pending for write
- const size_t packetSize = packet.GetPacketSize();
-
-#ifndef NDEBUG
- const size_t outgoingStreamSizeAfter = stream.CalculateOutgoingSize();
- const size_t xdcStreamSizeAfter = XdcStream.CalculateOutgoingSize();
-
- Y_ABORT_UNLESS(outgoingStreamSizeAfter == outgoingStreamSizeBefore + packetSize &&
- xdcStreamSizeAfter == xdcStreamSizeBefore + packet.GetExternalSize(),
- "outgoingStreamSizeBefore# %zu outgoingStreamSizeAfter# %zu packetSize# %zu"
- " xdcStreamSizeBefore# %zu xdcStreamSizeAfter# %zu externalSize# %" PRIu32,
- outgoingStreamSizeBefore, outgoingStreamSizeAfter, packetSize,
- xdcStreamSizeBefore, xdcStreamSizeAfter, packet.GetExternalSize());
-#endif
-
- // put outgoing packet metadata here
- if (data) {
- SendQueue.push_back(TOutgoingPacket{
- static_cast<ui32>(packetSize),
- static_cast<ui32>(packet.GetExternalSize())
- });
- }
-
- LOG_DEBUG_IC_SESSION("ICS22", "outgoing packet Serial# %" PRIu64 " Confirm# %" PRIu64 " DataSize# %" PRIu32
- " InflightDataAmount# %" PRIu64, serial, lastInputSerial, packet.GetDataSize(), InflightDataAmount);
-
- // reset forced packet sending timestamp as we have confirmed all received data
- ResetFlushLogic();
-
- ++PacketsGenerated;
-
- return packetSize;
- }
-
- void TInterconnectSessionTCP::DropConfirmed(ui64 confirm) {
- LOG_DEBUG_IC_SESSION("ICS23", "confirm count: %" PRIu64, confirm);
-
- Y_ABORT_UNLESS(LastConfirmed <= confirm && confirm <= OutputCounter,
- "%s confirm# %" PRIu64 " LastConfirmed# %" PRIu64 " OutputCounter# %" PRIu64,
- LogPrefix.data(), confirm, LastConfirmed, OutputCounter);
- LastConfirmed = confirm;
-
- std::optional<ui64> lastDroppedSerial;
- ui32 numDropped = 0;
-
- // drop confirmed packets; this also includes any auxiliary packets as their serial is set to zero, effectively
- // making Serial <= confirm true
- size_t bytesDropped = 0;
- size_t bytesDroppedFromXdc = 0;
- ui64 frontPacketSerial = OutputCounter - SendQueue.size() + 1;
- Y_DEBUG_ABORT_UNLESS(OutgoingIndex < SendQueue.size() || (OutgoingIndex == SendQueue.size() && !OutgoingOffset && !OutgoingStream),
- "OutgoingIndex# %zu SendQueue.size# %zu OutgoingOffset# %zu Unsent# %zu Total# %zu",
- OutgoingIndex, SendQueue.size(), OutgoingOffset, OutgoingStream.CalculateUnsentSize(),
- OutgoingStream.CalculateOutgoingSize());
- while (OutgoingIndex && frontPacketSerial <= confirm && SendQueue.front().ExternalSize <= XdcOffset) {
- auto& front = SendQueue.front();
- lastDroppedSerial.emplace(frontPacketSerial);
- XdcOffset -= front.ExternalSize;
- bytesDropped += front.PacketSize;
- bytesDroppedFromXdc += front.ExternalSize;
- ++numDropped;
-
- ++frontPacketSerial;
- SendQueue.pop_front();
- --OutgoingIndex;
- }
-
- if (!numDropped) {
- return;
- }
-
- const ui64 droppedDataAmount = bytesDropped + bytesDroppedFromXdc - sizeof(TTcpPacketHeader_v2) * numDropped;
- OutgoingStream.DropFront(bytesDropped);
- XdcStream.DropFront(bytesDroppedFromXdc);
- if (lastDroppedSerial) {
- ChannelScheduler->ForEach([&](TEventOutputChannel& channel) {
- channel.DropConfirmed(*lastDroppedSerial);
- });
- }
-
- PacketsConfirmed += numDropped;
- 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
-
- RearmCloseOnIdle();
- }
-
- void TInterconnectSessionTCP::FillSendingBuffer(TTcpPacketOutTask& task, ui64 serial) {
- ui32 bytesGenerated = 0;
-
- Y_ABORT_UNLESS(NumEventsInQueue);
- while (NumEventsInQueue) {
- TEventOutputChannel *channel = ChannelScheduler->PickChannelWithLeastConsumedWeight();
- Y_DEBUG_ABORT_UNLESS(!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_DEBUG_ABORT_UNLESS(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;
- Proxy->Metrics->SubOutputBuffersTotalSize(net);
- bytesGenerated += gross;
- Y_DEBUG_ABORT_UNLESS(!!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_ABORT_UNLESS(NumEventsInQueue);
- --NumEventsInQueue;
-
- if (!NumEventsInQueue) {
- SetOutputStuckFlag(false);
- }
- }
-
- if (!gross) { // no progress -- almost full packet buffer
- break;
- }
- }
-
- Y_ABORT_UNLESS(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,
- ORANGE,
- RED,
- };
- EFlag flagState = EFlag::RED;
-
- if (Socket) {
- flagState = EFlag::GREEN;
-
- do {
- auto lastInputDelay = TActivationContext::Monotonic() - 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
- flagState = EFlag::ORANGE;
- break;
- } else if (utilization > 500000) { // 1/2
- flagState = EFlag::YELLOW;
- }
- } while (false);
- }
-
- callback({TlsActivationContext->ExecutorThread.ActorSystem,
- Proxy->PeerNodeId,
- Proxy->Metrics->GetHumanFriendlyPeerHostName(),
- connected,
- flagState == EFlag::GREEN,
- flagState == EFlag::YELLOW,
- flagState == EFlag::ORANGE,
- flagState == EFlag::RED,
- ReceiveContext->ClockSkew_us.load()});
- }
-
- 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) {
- auto& lastpair = OutputQueueUtilization.Last();
- lastpair.second = now - lastpair.second;
- if (OutputStuckFlag)
- lastpair.first += now;
- }
-
- OutputQueueUtilization.Push(std::pair<ui64, ui64>(0, now));
- 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 {
- return DurationToCycles(TDuration::MicroSeconds(50));
- }
-
- void TInterconnectSessionTCP::IssuePingRequest() {
- const TMonotonic now = TActivationContext::Monotonic();
- if (now >= LastPingTimestamp + PingPeriodicity) {
- LOG_DEBUG_IC_SESSION("ICS00", "Issuing ping request");
- if (Socket) {
- MakePacket(false, GetCycleCountFast() | TTcpPacketBuf::PingRequestMask);
- MakePacket(false, TInstant::Now().MicroSeconds() | TTcpPacketBuf::ClockMask);
- }
- LastPingTimestamp = now;
- }
- }
-
- void TInterconnectSessionTCP::Handle(TEvProcessPingRequest::TPtr ev) {
- if (Socket) {
- MakePacket(false, ev->Get()->Payload | TTcpPacketBuf::PingResponseMask);
- GenerateTraffic();
- }
- }
-
- void TInterconnectSessionTCP::GenerateHttpInfo(NMon::TEvHttpInfoRes::TPtr& ev) {
- TStringStream str;
- ev->Get()->Output(str);
-
- HTML(str) {
- DIV_CLASS("panel panel-info") {
- DIV_CLASS("panel-heading") {
- str << "Session";
- }
- DIV_CLASS("panel-body") {
- TABLE_CLASS("table") {
- TABLEHEAD() {
- TABLER() {
- TABLEH() {
- str << "Sensor";
- }
- TABLEH() {
- 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 << "This page generated at";
- }
- TABLED() {
- str << TActivationContext::Now() << " / " << Now();
- }
- }
- TABLER() {
- TABLED() {
- str << "SelfID";
- }
- TABLED() {
- str << SelfId().ToString();
- }
- }
- TABLER() {
- TABLED() { str << "Frame version/Checksum"; }
- TABLED() { str << (Params.Encryption ? "v2/none" : Params.UseXxhash ? "v2/xxhash" : "v2/crc32c"); }
- }
-#define MON_VAR(NAME) \
- TABLER() { \
- TABLED() { \
- str << #NAME; \
- } \
- TABLED() { \
- str << NAME; \
- } \
- }
-
- MON_VAR(Created)
- MON_VAR(Params.UseExternalDataChannel)
- MON_VAR(NewConnectionSet)
- MON_VAR(ReceiverId)
- MON_VAR(MessagesGot)
- MON_VAR(MessagesWrittenToBuffer)
- MON_VAR(PacketsGenerated)
- MON_VAR(PacketsConfirmed)
- MON_VAR(ConfirmPacketsForcedBySize)
- MON_VAR(ConfirmPacketsForcedByTimeout)
-
- TABLER() {
- TABLED() {
- str << "Virtual self ID";
- }
- TABLED() {
- str << Proxy->SessionVirtualId.ToString();
- }
- }
- TABLER() {
- TABLED() {
- str << "Virtual peer ID";
- }
- TABLED() {
- str << Proxy->RemoteSessionVirtualId.ToString();
- }
- }
- TABLER() {
- TABLED() {
- str << "Socket";
- }
- TABLED() {
- str << (Socket ? i64(*Socket) : -1);
- }
- }
- TABLER() {
- TABLED() {
- str << "XDC socket";
- }
- TABLED() {
- str << (XdcSocket ? i64(*XdcSocket) : -1);
- }
- }
-
- ui32 unsentQueueSize = Socket ? Socket->GetUnsentQueueSize() : 0;
-
- const TMonotonic now = TActivationContext::Monotonic();
-
- MON_VAR(OutputStuckFlag)
- MON_VAR(SendQueue.size())
- MON_VAR(NumEventsInQueue)
- MON_VAR(TotalOutputQueueSize)
- MON_VAR(InflightDataAmount)
- MON_VAR(unsentQueueSize)
- MON_VAR(SendBufferSize)
- MON_VAR(now - LastInputActivityTimestamp)
- MON_VAR(now - LastPayloadActivityTimestamp)
- MON_VAR(LastHandshakeDone)
- MON_VAR(OutputCounter)
- MON_VAR(LastConfirmed)
- MON_VAR(FlushSchedule.size())
- MON_VAR(MaxFlushSchedule)
- MON_VAR(FlushEventsScheduled)
- MON_VAR(FlushEventsProcessed)
-
- MON_VAR(GetWriteBlockedTotal())
-
- MON_VAR(BytesWrittenToSocket)
- MON_VAR(XdcBytesSent)
-
- MON_VAR(OutgoingStream.CalculateOutgoingSize())
- MON_VAR(OutgoingStream.CalculateUnsentSize())
- MON_VAR(OutgoingStream.GetSendQueueSize())
- MON_VAR(OutgoingOffset)
- MON_VAR(OutgoingIndex)
-
- MON_VAR(OutOfBandStream.CalculateOutgoingSize())
- MON_VAR(OutOfBandStream.CalculateUnsentSize())
- MON_VAR(OutOfBandStream.GetSendQueueSize())
- MON_VAR(BytesAlignedForOutOfBand)
- MON_VAR(OutOfBandBytesSent)
-
- MON_VAR(XdcStream.CalculateOutgoingSize())
- MON_VAR(XdcStream.CalculateUnsentSize())
- MON_VAR(XdcStream.GetSendQueueSize())
- MON_VAR(XdcOffset)
-
- MON_VAR(CpuStarvationEvents)
- MON_VAR(CpuStarvationEventsOnWriteData)
-
- 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(now - LastPingTimestamp)
- MON_VAR(GetPingRTT())
- MON_VAR(clockSkew)
-
- MON_VAR(GetDeadPeerTimeout())
- MON_VAR(GetTotalInflightAmountOfData())
- MON_VAR(GetCloseOnIdleTimeout())
- MON_VAR(Subscribers.size())
- }
- }
- }
- }
- }
-
- auto h = std::make_unique<IEventHandle>(ev->Recipient, ev->Sender, new NMon::TEvHttpInfoRes(str.Str()));
- if (ReceiverId) {
- h->Rewrite(h->Type, ReceiverId);
- }
- TActivationContext::Send(h.release());
- }
-
- 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
deleted file mode 100644
index 64519b2667..0000000000
--- a/library/cpp/actors/interconnect/interconnect_tcp_session.h
+++ /dev/null
@@ -1,692 +0,0 @@
-#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 <library/cpp/actors/core/log.h>
-#include <library/cpp/actors/protos/services_common.pb.h>
-#include <library/cpp/actors/util/datetime.h>
-#include <library/cpp/actors/util/rope.h>
-#include <library/cpp/actors/util/funnel_queue.h>
-#include <library/cpp/actors/util/recentwnd.h>
-#include <library/cpp/monlib/dynamic_counters/counters.h>
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-
-#define XXH_INLINE_ALL
-#include <contrib/libs/xxhash/xxhash.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 "outgoing_stream.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;
- if (elapsed > 1000000) {
- 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 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
- };
-
- struct TReceiveContext: public TAtomicRefCount<TReceiveContext> {
- /* All invokations to these fields should be thread-safe */
-
- ui64 ControlPacketSendTimer = 0;
- ui64 ControlPacketId = 0;
-
- // last processed packet by input session
- std::atomic_uint64_t LastPacketSerialToConfirm = 0;
- static constexpr uint64_t LastPacketSerialToConfirmLockBit = 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 MainWriteBlocked = false;
- bool XdcWriteBlocked = false;
- bool MainReadPending = false;
- bool XdcReadPending = false;
-
- struct TPerChannelContext {
- struct TPendingEvent {
- TEventSerializationInfo SerializationInfo;
- TRope InternalPayload;
- TRope ExternalPayload;
- std::optional<TEventData> EventData;
-
- // number of bytes remaining through XDC channel
- size_t XdcSizeLeft = 0;
- };
-
- std::deque<TPendingEvent> PendingEvents;
- std::deque<TMutableContiguousSpan> XdcBuffers; // receive queue for current channel
- size_t FetchIndex = 0;
- size_t FetchOffset = 0;
-
- ui64 XdcCatchBytesRead = 0; // number of bytes actually read into cyclic buffer
- TRcBuf XdcCatchBuffer;
-
- void PrepareCatchBuffer();
- void ApplyCatchBuffer();
- void FetchBuffers(ui16 channel, size_t numBytes, std::deque<std::tuple<ui16, TMutableContiguousSpan>>& outQ);
- void DropFront(TRope *from, size_t numBytes);
- };
-
- std::array<TPerChannelContext, 16> ChannelArray;
- std::unordered_map<ui16, TPerChannelContext> ChannelMap;
- ui64 LastProcessedSerial = 0;
-
- TReceiveContext() {
- GetTimeFast(&StartTime);
- }
-
- // returns false if sessions needs to be terminated
- bool AdvanceLastPacketSerialToConfirm(ui64 nextValue) {
- for (;;) {
- uint64_t value = LastPacketSerialToConfirm.load();
- if (value & LastPacketSerialToConfirmLockBit) {
- return false;
- }
- Y_DEBUG_ABORT_UNLESS(value + 1 == nextValue);
- if (LastPacketSerialToConfirm.compare_exchange_weak(value, nextValue)) {
- return true;
- }
- }
- }
-
- ui64 LockLastPacketSerialToConfirm() {
- for (;;) {
- uint64_t value = LastPacketSerialToConfirm.load();
- if (value & LastPacketSerialToConfirmLockBit) {
- return value & ~LastPacketSerialToConfirmLockBit;
- }
- if (LastPacketSerialToConfirm.compare_exchange_strong(value, value | LastPacketSerialToConfirmLockBit)) {
- return value;
- }
- }
- }
-
- void UnlockLastPacketSerialToConfirm() {
- LastPacketSerialToConfirm &= ~LastPacketSerialToConfirmLockBit;
- }
-
- ui64 GetLastPacketSerialToConfirm() {
- return LastPacketSerialToConfirm.load() & ~LastPacketSerialToConfirmLockBit;
- }
- };
-
- class TInputSessionTCP
- : public TActorBootstrapped<TInputSessionTCP>
- , public TInterconnectLoggingBase
- {
- enum {
- EvCheckDeadPeer = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvResumeReceiveData,
- };
-
- struct TEvCheckDeadPeer : TEventLocal<TEvCheckDeadPeer, EvCheckDeadPeer> {};
-
- public:
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::INTERCONNECT_SESSION_TCP;
- }
-
- TInputSessionTCP(const TActorId& sessionId,
- TIntrusivePtr<NInterconnect::TStreamSocket> socket,
- TIntrusivePtr<NInterconnect::TStreamSocket> xdcSocket,
- TIntrusivePtr<TReceiveContext> context,
- TInterconnectProxyCommon::TPtr common,
- std::shared_ptr<IInterconnectMetrics> metrics,
- ui32 nodeId,
- ui64 lastConfirmed,
- TDuration deadPeerTimeout,
- TSessionParams params);
-
- private:
- friend class TActorBootstrapped<TInputSessionTCP>;
-
- void Bootstrap();
-
- struct TExReestablishConnection {
- TDisconnectReason Reason;
- };
-
- struct TExDestroySession {
- TDisconnectReason Reason;
- };
-
- STATEFN(WorkingState);
-
- STRICT_STFUNC(WorkingStateImpl,
- cFunc(TEvents::TSystem::PoisonPill, PassAway)
- hFunc(TEvPollerReady, Handle)
- hFunc(TEvPollerRegisterResult, Handle)
- cFunc(EvResumeReceiveData, ReceiveData)
- cFunc(TEvInterconnect::TEvCloseInputSession::EventType, CloseInputSession)
- cFunc(EvCheckDeadPeer, HandleCheckDeadPeer)
- cFunc(TEvConfirmUpdate::EventType, HandleConfirmUpdate)
- hFunc(NMon::TEvHttpInfoRes, GenerateHttpInfo)
- )
-
- private:
- TRope IncomingData;
-
- const TActorId SessionId;
- TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
- TIntrusivePtr<NInterconnect::TStreamSocket> XdcSocket;
- TPollerToken::TPtr PollerToken;
- TPollerToken::TPtr XdcPollerToken;
- TIntrusivePtr<TReceiveContext> Context;
- TInterconnectProxyCommon::TPtr Common;
- const ui32 NodeId;
- const TSessionParams Params;
- XXH3_state_t XxhashState;
- XXH3_state_t XxhashXdcState;
-
- size_t PayloadSize;
- ui32 ChecksumExpected, Checksum;
- bool IgnorePayload;
- TRope Payload;
- enum class EState {
- HEADER,
- PAYLOAD,
- };
- EState State = EState::HEADER;
- ui64 CurrentSerial = 0;
-
- std::vector<char> XdcCommands;
-
- struct TInboundPacket {
- ui64 Serial;
- size_t XdcUnreadBytes; // number of unread bytes from XDC stream for this exact unprocessed packet
- };
- std::deque<TInboundPacket> InboundPacketQ;
- std::deque<std::tuple<ui16, TMutableContiguousSpan>> XdcInputQ; // target buffers for the XDC stream with channel reference
- std::deque<std::tuple<ui16, ui32>> XdcChecksumQ; // (size, expectedChecksum)
- ui32 XdcCurrentChecksum = 0;
-
- // catch stream -- used after TCP reconnect to match XDC stream with main packet stream
- struct TXdcCatchStream {
- TRcBuf Buffer;
- ui64 BytesPending = 0;
- ui64 BytesProcessed = 0;
- std::deque<std::tuple<ui16, bool, size_t>> Markup; // a queue of tuples (channel, apply, bytes)
- bool Ready = false;
- bool Applied = false;
- };
- TXdcCatchStream XdcCatchStream;
-
- THolder<TEvUpdateFromInputSession> UpdateFromInputSession;
-
- ui64 ConfirmedByInput;
-
- std::shared_ptr<IInterconnectMetrics> Metrics;
- std::array<ui32, 16> InputTrafficArray;
- THashMap<ui16, ui32> InputTrafficMap;
-
- bool CloseInputSessionRequested = false;
-
- void CloseInputSession();
-
- void Handle(TEvPollerReady::TPtr ev);
- void Handle(TEvPollerRegisterResult::TPtr ev);
- void HandleConfirmUpdate();
- void ReceiveData();
- void ProcessHeader();
- void ProcessPayload(ui64 *numDataBytes);
- void ProcessInboundPacketQ(ui64 numXdcBytesRead);
- void ProcessXdcCommand(ui16 channel, TReceiveContext::TPerChannelContext& context);
- void ProcessEvents(TReceiveContext::TPerChannelContext& context);
- ssize_t Read(NInterconnect::TStreamSocket& socket, const TPollerToken::TPtr& token, bool *readPending,
- const TIoVec *iov, size_t num);
- bool ReadMore();
- bool ReadXdcCatchStream(ui64 *numDataBytes);
- void ApplyXdcCatchStream();
- bool ReadXdc(ui64 *numDataBytes);
- void HandleXdcChecksum(TContiguousSpan span);
-
- TReceiveContext::TPerChannelContext& GetPerChannelContext(ui16 channel) const;
-
- void PassAway() override;
-
- TDeque<TRcBuf> Buffers;
-
- size_t CurrentBuffers = 1; // number of buffers currently required to allocate
- static constexpr size_t MaxBuffers = 72; // maximum buffers possible
- static constexpr int BitsPerUsageCount = 5;
- static constexpr size_t ItemsPerUsageCount = sizeof(ui64) * CHAR_BIT / BitsPerUsageCount;
- std::array<ui64, (MaxBuffers + ItemsPerUsageCount - 1) / ItemsPerUsageCount> UsageHisto; // read count histogram
-
- void PreallocateBuffers();
-
- inline ui64 GetMaxCyclesPerEvent() const {
- return DurationToCycles(TDuration::MicroSeconds(500));
- }
-
- const TDuration DeadPeerTimeout;
- TMonotonic 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);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Stats
-
- ui64 BytesReadFromSocket = 0;
- ui64 PacketsReadFromSocket = 0;
- ui64 DataPacketsReadFromSocket = 0;
- ui64 IgnoredDataPacketsFromSocket = 0;
-
- ui64 BytesReadFromXdcSocket = 0;
- ui64 XdcSections = 0;
- ui64 XdcRefs = 0;
-
- ui64 CpuStarvationEvents = 0;
-
- void GenerateHttpInfo(NMon::TEvHttpInfoRes::TPtr ev);
- };
-
- class TInterconnectSessionTCP
- : public TActor<TInterconnectSessionTCP>
- , public TInterconnectLoggingBase
- {
- enum {
- 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))
- {}
- };
-
- const TInstant Created;
- TInstant NewConnectionSet;
- ui64 MessagesGot = 0;
- ui64 MessagesWrittenToBuffer = 0;
- ui64 PacketsGenerated = 0;
- ui64 BytesWrittenToSocket = 0;
- ui64 PacketsConfirmed = 0;
- ui64 BytesAlignedForOutOfBand = 0;
- ui64 OutOfBandBytesSent = 0;
- ui64 CpuStarvationEvents = 0;
- ui64 CpuStarvationEventsOnWriteData = 0;
-
- public:
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::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;
- }
-
- 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);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- std::optional<TTimeLimit> TimeLimit;
-
- STATEFN(StateFunc) {
- TimeLimit.emplace(GetMaxCyclesPerEvent());
- STRICT_STFUNC_BODY(
- 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 IssueRam(bool batching);
- void HandleRam(TEvRam::TPtr& ev);
- void GenerateTraffic();
- void ProducePackets();
-
- size_t GetUnsentSize() const {
- return OutgoingStream.CalculateUnsentSize() + OutOfBandStream.CalculateUnsentSize() +
- XdcStream.CalculateUnsentSize();
- }
-
- size_t GetUnsentLimit() const {
- return 128 * 1024;
- }
-
- void SendUpdateToWhiteboard(bool connected = true);
- ui32 CalculateQueueUtilization();
-
- void Handle(TEvPollerReady::TPtr& ev);
- void Handle(TEvPollerRegisterResult::TPtr ev);
- void WriteData();
- ssize_t Write(NInterconnect::TOutgoingStream& stream, NInterconnect::TStreamSocket& socket, size_t maxBytes);
-
- ui32 MakePacket(bool data, TMaybe<ui64> pingMask = {});
- void FillSendingBuffer(TTcpPacketOutTask& packet, ui64 serial);
- void 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
-
- TMonotonic LastPingTimestamp;
- static constexpr TDuration PingPeriodicity = TDuration::Seconds(1);
- void IssuePingRequest();
- void Handle(TEvProcessPingRequest::TPtr ev);
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- TMonotonic LastInputActivityTimestamp;
- TMonotonic 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());
- }
-
- void RearmCloseOnIdle() {
- if (!NumEventsInQueue && OutputCounter == LastConfirmed) {
- CloseOnIdleWatchdog.Rearm(SelfId());
- } else {
- CloseOnIdleWatchdog.Disarm();
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- const TSessionParams Params;
- TMaybe<TEventHolderPool> Pool;
- TMaybe<TChannelScheduler> ChannelScheduler;
- ui64 TotalOutputQueueSize;
- bool OutputStuckFlag;
- TRecentWnd<std::pair<ui64, ui64>> OutputQueueUtilization;
- size_t NumEventsInQueue = 0;
-
- void SetOutputStuckFlag(bool state);
- void SwitchStuckPeriod();
-
- NInterconnect::TOutgoingStream OutgoingStream;
- NInterconnect::TOutgoingStream OutOfBandStream;
- NInterconnect::TOutgoingStream XdcStream;
-
- struct TOutgoingPacket {
- ui32 PacketSize; // including header
- ui32 ExternalSize;
- };
- std::deque<TOutgoingPacket> SendQueue; // packet boundaries
- size_t OutgoingOffset = 0;
- size_t XdcOffset = 0;
- size_t OutgoingIndex = 0; // index into current packet in SendQueue
- size_t ForcedWriteLength = 0;
-
- ui64 XdcBytesSent = 0;
-
- ui64 WriteBlockedCycles = 0; // start of current block period
- TDuration WriteBlockedTotal; // total incremental duration that session has been blocked
- bool WriteBlockedByFullSendBuffer = false;
-
- TDuration GetWriteBlockedTotal() const {
- return WriteBlockedTotal + (WriteBlockedByFullSendBuffer
- ? TDuration::Seconds(NHPTimer::GetSeconds(GetCycleCountFast() - WriteBlockedCycles))
- : TDuration::Zero());
- }
-
- ui64 OutputCounter;
-
- TInstant LastHandshakeDone;
-
- TIntrusivePtr<NInterconnect::TStreamSocket> Socket;
- TIntrusivePtr<NInterconnect::TStreamSocket> XdcSocket;
- TPollerToken::TPtr PollerToken;
- TPollerToken::TPtr XdcPollerToken;
- 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;
- TMonotonic ForcePacketTimestamp = TMonotonic::Max();
- TPriorityQueue<TMonotonic, TVector<TMonotonic>, std::greater<TMonotonic>> FlushSchedule;
- size_t MaxFlushSchedule = 0;
- ui64 FlushEventsScheduled = 0;
- ui64 FlushEventsProcessed = 0;
-
- void SetForcePacketTimestamp(TDuration period);
- void ScheduleFlush();
- void HandleFlush();
- void ResetFlushLogic();
-
- void GenerateHttpInfo(NMon::TEvHttpInfoRes::TPtr& ev);
-
- TIntrusivePtr<TReceiveContext> ReceiveContext;
- TActorId ReceiverId;
- TDuration Ping;
-
- ui64 ConfirmPacketsForcedBySize = 0;
- ui64 ConfirmPacketsForcedByTimeout = 0;
-
- ui64 LastConfirmed = 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;
-
- public:
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::INTERCONNECT_SESSION_KILLER;
- }
-
- TInterconnectSessionKiller(TInterconnectProxyCommon::TPtr common)
- : Common(common)
- {
- }
-
- 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);
- Become(&TInterconnectSessionKiller::StateFunc);
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvSessionBufferSizeResponse, ProcessResponse)
- cFunc(TEvents::TEvUndelivered::EventType, ProcessUndelivered)
- )
-
- 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);
- AtomicUnlock(&Common->StartedSessionKiller);
- PassAway();
- }
- }
-
- void ProcessUndelivered() {
- RepliesReceived++;
- }
- };
-
- void CreateSessionKillingActor(TInterconnectProxyCommon::TPtr common);
-
-}
diff --git a/library/cpp/actors/interconnect/load.cpp b/library/cpp/actors/interconnect/load.cpp
deleted file mode 100644
index 20ca0ef8a9..0000000000
--- a/library/cpp/actors/interconnect/load.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-#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);
- )
-
- void Handle(TEvLoadMessage::TPtr& ev, const TActorContext& ctx) {
- 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))
- {}
-
- static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::EActivityType::INTERCONNECT_LOAD_RESPONDER;
- }
-
- 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);
- )
-
- 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 {
- for (const TActorId& actorId : Slaves) {
- ctx.Send(actorId, new TEvents::TEvPoisonPill);
- }
- TActorBootstrapped::Die(ctx);
- }
-
- public:
- static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::EActivityType::INTERCONNECT_LOAD_RESPONDER;
- }
-
- 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>();
- };
-
- IActor* CreateLoadResponderActor() {
- return new TLoadResponderMasterActor();
- }
-
- TActorId MakeLoadResponderActorId(ui32 nodeId) {
- 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;
-
- TMessageInfo(const TInstant& sendTimestamp)
- : SendTimestamp(sendTimestamp)
- {
- }
- };
-
- 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:
- static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::EActivityType::INTERCONNECT_LOAD_ACTOR;
- }
-
- TLoadActor(const TLoadParams& params)
- : 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) {
- 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);
- }
-
- 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);
-
- 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);
- }
- }
-
- 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;
-
- void PutTimeoutQueueItem(const TActorContext& ctx, TString id) {
- 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);
- }
-
- 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);
-
- void SchedulePublishResults(const TActorContext& ctx) {
- 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());
- 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);
- msg << Sprintf(" %.4f# %s", q, v[pos].ToString().data());
- }
- 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);
- }
- };
-
- IActor* CreateLoadActor(const TLoadParams& params) {
- return new TLoadActor(params);
- }
-
-}
diff --git a/library/cpp/actors/interconnect/load.h b/library/cpp/actors/interconnect/load.h
deleted file mode 100644
index 0a01a0dc04..0000000000
--- a/library/cpp/actors/interconnect/load.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-
-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;
- 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
- bool SoftLoad; // is the load soft?
- TDuration Duration; // test duration
- 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
deleted file mode 100644
index 010a4aa93b..0000000000
--- a/library/cpp/actors/interconnect/logging.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#pragma once
-
-#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()); \
- } while (false)
-
-#define LOG_LOG_NET(priority, NODE_ID, FMT, ...) \
- do { \
- const TActorContext& ctx = ::NActors::TActivationContext::AsActorContext(); \
- LOG_LOG(ctx, (priority), ::NActorsServices::INTERCONNECT_NETWORK, "[%" PRIu32 " <-> %" PRIu32 "] %s", \
- 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_TRACE_IC(marker, ...) LOG_LOG_IC(::NActorsServices::INTERCONNECT, marker, ::NActors::NLog::PRI_TRACE, __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)
- : LogPrefix(prefix)
- {
- }
-
- void SetPrefix(TString logPrefix) const {
- logPrefix.swap(const_cast<TString&>(LogPrefix));
- }
- };
-}
diff --git a/library/cpp/actors/interconnect/mock/CMakeLists.darwin-arm64.txt b/library/cpp/actors/interconnect/mock/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index c29d87b0ce..0000000000
--- a/library/cpp/actors/interconnect/mock/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(actors-interconnect-mock)
-target_link_libraries(actors-interconnect-mock PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-interconnect
-)
-target_sources(actors-interconnect-mock PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/mock/ic_mock.cpp
-)
diff --git a/library/cpp/actors/interconnect/mock/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/interconnect/mock/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index c29d87b0ce..0000000000
--- a/library/cpp/actors/interconnect/mock/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(actors-interconnect-mock)
-target_link_libraries(actors-interconnect-mock PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-interconnect
-)
-target_sources(actors-interconnect-mock PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/mock/ic_mock.cpp
-)
diff --git a/library/cpp/actors/interconnect/mock/CMakeLists.linux-aarch64.txt b/library/cpp/actors/interconnect/mock/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 85d0cf4696..0000000000
--- a/library/cpp/actors/interconnect/mock/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(actors-interconnect-mock)
-target_link_libraries(actors-interconnect-mock PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-interconnect
-)
-target_sources(actors-interconnect-mock PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/mock/ic_mock.cpp
-)
diff --git a/library/cpp/actors/interconnect/mock/CMakeLists.linux-x86_64.txt b/library/cpp/actors/interconnect/mock/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 85d0cf4696..0000000000
--- a/library/cpp/actors/interconnect/mock/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(actors-interconnect-mock)
-target_link_libraries(actors-interconnect-mock PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-interconnect
-)
-target_sources(actors-interconnect-mock PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/mock/ic_mock.cpp
-)
diff --git a/library/cpp/actors/interconnect/mock/CMakeLists.txt b/library/cpp/actors/interconnect/mock/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/interconnect/mock/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/interconnect/mock/CMakeLists.windows-x86_64.txt b/library/cpp/actors/interconnect/mock/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index c29d87b0ce..0000000000
--- a/library/cpp/actors/interconnect/mock/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(actors-interconnect-mock)
-target_link_libraries(actors-interconnect-mock PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-interconnect
-)
-target_sources(actors-interconnect-mock PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/mock/ic_mock.cpp
-)
diff --git a/library/cpp/actors/interconnect/mock/ic_mock.cpp b/library/cpp/actors/interconnect/mock/ic_mock.cpp
deleted file mode 100644
index 81e181b673..0000000000
--- a/library/cpp/actors/interconnect/mock/ic_mock.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-#include "ic_mock.h"
-#include <library/cpp/actors/core/interconnect.h>
-#include <util/system/yield.h>
-#include <thread>
-#include <deque>
-
-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_ABORT_UNLESS(!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(IEventHandle::ForwardOnNondelivery(std::move(ev), 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_ABORT();
- }
- }
- };
-
- 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)
- {}
-
- static constexpr char ActorName[] = "SESSION_MOCK_ACTOR";
-
- void Terminate() {
- for (auto&& ev : std::exchange(Queue, {})) {
- TActivationContext::Send(IEventHandle::ForwardOnNondelivery(std::move(ev), TEvents::TEvUndelivered::Disconnected));
- }
- for (const auto& kv : Subscribers) {
- Send(kv.first, new TEvInterconnect::TEvNodeDisconnected(Proxy->PeerNodeId), 0, kv.second);
- }
- Y_ABORT_UNLESS(Proxy->Session == this);
- Proxy->Session = nullptr;
- PassAway();
- }
-
- void HandleForward(TAutoPtr<IEventHandle> ev) {
- if (CheckNodeStatus(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 (CheckNodeStatus(ev)) {
- Subscribe(ev->Sender, ev->Cookie);
- }
- }
-
- void Handle(TEvents::TEvSubscribe::TPtr ev) {
- if (CheckNodeStatus(ev)) {
- Subscribe(ev->Sender, ev->Cookie);
- }
- }
-
- void Handle(TEvents::TEvUnsubscribe::TPtr ev) {
- if (CheckNodeStatus(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)
- hFunc(TEvInterconnect::TEvNodeInfo, HandleNodeInfo)
- cFunc(TEvents::TSystem::Poison, HandlePoison)
- cFunc(EvRam, HandleRam)
- )
-
- private:
- enum EPeerNodeStatus {
- UNKNOWN,
- EXISTS,
- MISSING
- };
-
- bool IsWaitingForNodeInfo = false;
- std::deque<std::unique_ptr<IEventHandle>> WaitingConnections;
- EPeerNodeStatus PeerNodeStatus = EPeerNodeStatus::UNKNOWN;
-
- void Subscribe(const TActorId& actorId, ui64 cookie) {
- Subscribers[actorId] = cookie;
- Send(actorId, new TEvInterconnect::TEvNodeConnected(Proxy->PeerNodeId), 0, cookie);
- }
-
- template <typename TEvent>
- bool CheckNodeStatus(TAutoPtr<TEventHandle<TEvent>>& ev) {
- if (PeerNodeStatus != EPeerNodeStatus::EXISTS) {
- std::unique_ptr<IEventHandle> tmp(ev.Release());
- CheckNonexistentNode(tmp);
- return false;
- }
- return true;
- }
-
- bool CheckNodeStatus(TAutoPtr<IEventHandle>& ev) {
- if (PeerNodeStatus != EPeerNodeStatus::EXISTS) {
- std::unique_ptr<IEventHandle> tmp(ev.Release());
- CheckNonexistentNode(tmp);
- return false;
- }
- return true;
- }
-
- void CheckNonexistentNode(std::unique_ptr<IEventHandle>& ev) {
- if (PeerNodeStatus == EPeerNodeStatus::UNKNOWN) {
- WaitingConnections.emplace_back(ev.release());
- if (!IsWaitingForNodeInfo) {
- Send(Proxy->Common->NameserviceId, new TEvInterconnect::TEvGetNode(Proxy->PeerNodeId));
- IsWaitingForNodeInfo = true;
- }
- } else if (PeerNodeStatus == EPeerNodeStatus::MISSING) {
- switch (ev->GetTypeRewrite()) {
- case TEvInterconnect::EvForward:
- if (ev->Flags & IEventHandle::FlagSubscribeOnSession) {
- Send(ev->Sender, new TEvInterconnect::TEvNodeDisconnected(Proxy->PeerNodeId), 0, ev->Cookie);
- }
- TActivationContext::Send(IEventHandle::ForwardOnNondelivery(std::move(ev), TEvents::TEvUndelivered::Disconnected));
- break;
-
- case TEvents::TEvSubscribe::EventType:
- case TEvInterconnect::TEvConnectNode::EventType:
- Send(ev->Sender, new TEvInterconnect::TEvNodeDisconnected(Proxy->PeerNodeId), 0, ev->Cookie);
- break;
-
- case TEvents::TEvUnsubscribe::EventType:
- break;
-
- default:
- Y_ABORT();
- }
- }
- }
-
- void HandleNodeInfo(TEvInterconnect::TEvNodeInfo::TPtr ev) {
- Y_ABORT_UNLESS(IsWaitingForNodeInfo);
- if (!ev->Get()->Node) {
- PeerNodeStatus = EPeerNodeStatus::MISSING;
- } else {
- PeerNodeStatus = EPeerNodeStatus::EXISTS;
- }
- IsWaitingForNodeInfo = false;
- while (!WaitingConnections.empty()) {
- TAutoPtr<IEventHandle> tmp(WaitingConnections.front().release());
- WaitingConnections.pop_front();
- Receive(tmp);
- }
- }
- };
-
- 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))
- {}
-
- static constexpr char ActorName[] = "PROXY_MOCK_ACTOR";
-
- 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());
- RegisterWithSameMailbox(Session);
- }
- return Session;
- }
-
- void HandleSessionEvent(TAutoPtr<IEventHandle> ev) {
- auto *session = GetSession();
- InvokeOtherActor(*session, &TSessionMockActor::Receive, ev);
- }
-
- 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_ABORT_UNLESS(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_ABORT_UNLESS(nodeId != peerNodeId);
- Y_ABORT_UNLESS(nodeId);
- Y_ABORT_UNLESS(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
deleted file mode 100644
index 636bdc2b7f..0000000000
--- a/library/cpp/actors/interconnect/mock/ic_mock.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#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
deleted file mode 100644
index d097e3f094..0000000000
--- a/library/cpp/actors/interconnect/mock/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-LIBRARY()
-
-SRCS(
- ic_mock.cpp
- ic_mock.h
-)
-
-SUPPRESSIONS(tsan.supp)
-
-PEERDIR(
- library/cpp/actors/interconnect
-)
-
-END()
diff --git a/library/cpp/actors/interconnect/outgoing_stream.h b/library/cpp/actors/interconnect/outgoing_stream.h
deleted file mode 100644
index 304fa925a8..0000000000
--- a/library/cpp/actors/interconnect/outgoing_stream.h
+++ /dev/null
@@ -1,272 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/event_load.h>
-#include <library/cpp/actors/util/rc_buf.h>
-#include <library/cpp/containers/stack_vector/stack_vec.h>
-#include <deque>
-
-namespace NInterconnect {
-
- template<size_t TotalSize>
- class TOutgoingStreamT {
- static constexpr size_t BufferSize = TotalSize - sizeof(ui32) * 2;
-
- struct TBuffer {
- char Data[BufferSize];
- ui32 RefCount;
- ui32 Index;
-
- struct TDeleter {
- void operator ()(TBuffer *buffer) const {
- free(buffer);
- }
- };
- };
-
- static_assert(sizeof(TBuffer) == TotalSize);
-
- struct TSendChunk {
- TContiguousSpan Span;
- TBuffer *Buffer;
- };
-
- std::vector<std::unique_ptr<TBuffer, typename TBuffer::TDeleter>> Buffers;
- TBuffer *AppendBuffer = nullptr;
- size_t AppendOffset = BufferSize; // into the last buffer
- std::deque<TSendChunk> SendQueue;
- size_t SendQueuePos = 0;
- size_t SendOffset = 0;
- size_t UnsentBytes = 0;
-
- public:
- operator bool() const {
- return SendQueuePos != SendQueue.size();
- }
-
- size_t CalculateOutgoingSize() const {
- size_t res = 0;
- for (const TSendChunk& chunk : SendQueue) {
- res += chunk.Span.size();
- }
- return res;
- }
-
- size_t CalculateUnsentSize() const {
-#ifndef NDEBUG
- size_t res = 0;
- for (auto it = SendQueue.begin() + SendQueuePos; it != SendQueue.end(); ++it) {
- res += it->Span.size();
- }
- Y_ABORT_UNLESS(UnsentBytes == res - SendOffset);
-#endif
- return UnsentBytes;
- }
-
- size_t GetSendQueueSize() const {
- return SendQueue.size();
- }
-
- TMutableContiguousSpan AcquireSpanForWriting(size_t maxLen) {
- if (!maxLen) {
- return {nullptr, 0};
- }
- if (AppendOffset == BufferSize) { // we have no free buffer, allocate one
- Buffers.emplace_back(static_cast<TBuffer*>(malloc(sizeof(TBuffer))));
- AppendBuffer = Buffers.back().get();
- Y_ABORT_UNLESS(AppendBuffer);
- AppendBuffer->RefCount = 1; // through AppendBuffer pointer
- AppendBuffer->Index = Buffers.size() - 1;
- AppendOffset = 0;
- }
- return {AppendBuffer->Data + AppendOffset, Min(maxLen, BufferSize - AppendOffset)};
- }
-
- void Align() {
- if (AppendOffset != BufferSize) {
- AppendOffset += -(reinterpret_cast<uintptr_t>(AppendBuffer->Data) + AppendOffset) & 63;
- if (AppendOffset > BufferSize) {
- AppendOffset = BufferSize;
- DropBufferReference(std::exchange(AppendBuffer, nullptr));
- }
- }
- }
-
- void Append(TContiguousSpan span) {
- if (AppendBuffer && span.data() == AppendBuffer->Data + AppendOffset) { // the only valid case to use previously acquired span
- AppendAcquiredSpan(span);
- } else {
-#ifndef NDEBUG
- // ensure this span does not point into any existing buffer part
- const char *begin = span.data();
- const char *end = span.data() + span.size();
- for (const auto& buffer : Buffers) {
- const char *bufferBegin = buffer->Data;
- const char *bufferEnd = bufferBegin + BufferSize;
- if (bufferBegin < end && begin < bufferEnd) {
- Y_ABORT();
- }
- }
-#endif
- AppendSpanWithGlueing(span, nullptr);
- }
- }
-
- void Write(TContiguousSpan in) {
- while (in.size()) {
- auto outChunk = AcquireSpanForWriting(in.size());
- memcpy(outChunk.data(), in.data(), outChunk.size());
- AppendAcquiredSpan(outChunk);
- in = in.SubSpan(outChunk.size(), Max<size_t>());
- }
- }
-
- using TBookmark = TStackVec<TMutableContiguousSpan, 2>;
-
- TBookmark Bookmark(size_t len) {
- TBookmark bookmark;
-
- while (len) {
- const auto span = AcquireSpanForWriting(len);
- AppendAcquiredSpan(span);
- bookmark.push_back(span);
- len -= span.size();
- }
-
- return bookmark;
- }
-
- void WriteBookmark(TBookmark&& bookmark, TContiguousSpan in) {
- for (auto& outChunk : bookmark) {
- Y_DEBUG_ABORT_UNLESS(outChunk.size() <= in.size());
- memcpy(outChunk.data(), in.data(), outChunk.size());
- in = in.SubSpan(outChunk.size(), Max<size_t>());
- }
- }
-
- void Rewind() {
- SendQueuePos = 0;
- SendOffset = 0;
- UnsentBytes = 0;
- for (const auto& item : SendQueue) {
- UnsentBytes += item.Span.size();
- }
- }
-
- void RewindToEnd() {
- SendQueuePos = SendQueue.size();
- SendOffset = 0;
- UnsentBytes = 0;
- }
-
- template<typename T>
- void ProduceIoVec(T& container, size_t maxItems, size_t maxBytes) {
- size_t offset = SendOffset;
- for (auto it = SendQueue.begin() + SendQueuePos; it != SendQueue.end() && std::size(container) < maxItems && maxBytes; ++it) {
- const TContiguousSpan span = it->Span.SubSpan(offset, maxBytes);
- container.push_back(NActors::TConstIoVec{span.data(), span.size()});
- offset = 0;
- maxBytes -= span.size();
- }
- }
-
- void Advance(size_t numBytes) { // called when numBytes portion of data has been sent
- Y_DEBUG_ABORT_UNLESS(numBytes == 0 || SendQueuePos != SendQueue.size());
- Y_DEBUG_ABORT_UNLESS(numBytes <= UnsentBytes);
- SendOffset += numBytes;
- UnsentBytes -= numBytes;
- for (auto it = SendQueue.begin() + SendQueuePos; SendOffset && it->Span.size() <= SendOffset; ++SendQueuePos, ++it) {
- SendOffset -= it->Span.size();
- Y_DEBUG_ABORT_UNLESS(SendOffset == 0 || SendQueuePos != SendQueue.size() - 1);
- }
- }
-
- void DropFront(size_t numBytes) { // drops first numBytes from the queue, freeing buffers when necessary
- while (numBytes) {
- Y_DEBUG_ABORT_UNLESS(!SendQueue.empty());
- auto& front = SendQueue.front();
- if (numBytes < front.Span.size()) {
- front.Span = front.Span.SubSpan(numBytes, Max<size_t>());
- if (SendQueuePos == 0) {
- Y_DEBUG_ABORT_UNLESS(numBytes <= SendOffset, "numBytes# %zu SendOffset# %zu SendQueuePos# %zu"
- " SendQueue.size# %zu CalculateUnsentSize# %zu", numBytes, SendOffset, SendQueuePos,
- SendQueue.size(), CalculateUnsentSize());
- SendOffset -= numBytes;
- }
- break;
- } else {
- numBytes -= front.Span.size();
- }
- Y_DEBUG_ABORT_UNLESS(!front.Buffer || (front.Span.data() >= front.Buffer->Data &&
- front.Span.data() + front.Span.size() <= front.Buffer->Data + BufferSize));
- DropBufferReference(front.Buffer);
- SendQueue.pop_front();
- if (SendQueuePos) {
- --SendQueuePos;
- } else {
- SendOffset = 0;
- }
- }
- }
-
- template<typename T>
- void ScanLastBytes(size_t numBytes, T&& callback) const {
- auto it = SendQueue.end();
- ssize_t offset = -numBytes;
- while (offset < 0) {
- Y_DEBUG_ABORT_UNLESS(it != SendQueue.begin());
- const TSendChunk& chunk = *--it;
- offset += chunk.Span.size();
- }
- for (; it != SendQueue.end(); ++it, offset = 0) {
- callback(it->Span.SubSpan(offset, Max<size_t>()));
- }
- }
-
- private:
- void AppendAcquiredSpan(TContiguousSpan span) {
- TBuffer *buffer = AppendBuffer;
- Y_DEBUG_ABORT_UNLESS(buffer);
- Y_DEBUG_ABORT_UNLESS(span.data() == AppendBuffer->Data + AppendOffset);
- AppendOffset += span.size();
- Y_DEBUG_ABORT_UNLESS(AppendOffset <= BufferSize);
- if (AppendOffset == BufferSize) {
- AppendBuffer = nullptr;
- } else {
- ++buffer->RefCount;
- }
- AppendSpanWithGlueing(span, buffer);
- }
-
- void AppendSpanWithGlueing(TContiguousSpan span, TBuffer *buffer) {
- UnsentBytes += span.size();
- if (!SendQueue.empty()) {
- auto& back = SendQueue.back();
- if (back.Span.data() + back.Span.size() == span.data()) { // check if it is possible just to extend the last span
- Y_DEBUG_ABORT_UNLESS(buffer == back.Buffer);
- if (SendQueuePos == SendQueue.size()) {
- --SendQueuePos;
- SendOffset = back.Span.size();
- }
- back.Span = {back.Span.data(), back.Span.size() + span.size()};
- DropBufferReference(buffer);
- return;
- }
- }
- SendQueue.push_back(TSendChunk{span, buffer});
- }
-
- void DropBufferReference(TBuffer *buffer) {
- if (buffer && !--buffer->RefCount) {
- const size_t index = buffer->Index;
- auto& cell = Buffers[index];
- Y_DEBUG_ABORT_UNLESS(cell.get() == buffer);
- std::swap(cell, Buffers.back());
- cell->Index = index;
- Buffers.pop_back();
- }
- }
- };
-
- using TOutgoingStream = TOutgoingStreamT<262144>;
-
-} // NInterconnect
diff --git a/library/cpp/actors/interconnect/packet.cpp b/library/cpp/actors/interconnect/packet.cpp
deleted file mode 100644
index 9ba173e330..0000000000
--- a/library/cpp/actors/interconnect/packet.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "packet.h"
-
-#include <library/cpp/actors/core/probes.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;
- 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;
-}
diff --git a/library/cpp/actors/interconnect/packet.h b/library/cpp/actors/interconnect/packet.h
deleted file mode 100644
index 0a748cda2a..0000000000
--- a/library/cpp/actors/interconnect/packet.h
+++ /dev/null
@@ -1,304 +0,0 @@
-#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/containers/stack_vector/stack_vec.h>
-#include <library/cpp/actors/util/rope.h>
-#include <library/cpp/actors/prof/tag.h>
-#include <library/cpp/actors/wilson/wilson_span.h>
-#include <library/cpp/digest/crc32c/crc32c.h>
-#include <library/cpp/lwtrace/shuttle.h>
-#include <util/generic/string.h>
-#include <util/generic/list.h>
-
-#define XXH_INLINE_ALL
-#include <contrib/libs/xxhash/xxhash.h>
-
-#include "types.h"
-#include "outgoing_stream.h"
-
-#ifndef FORCE_EVENT_CHECKSUM
-#define FORCE_EVENT_CHECKSUM 0
-#endif
-
-// WARNING: turning this feature on will make protocol incompatible with ordinary Interconnect, use with caution
-#define IC_FORCE_HARDENED_PACKET_CHECKS 0
-
-#if IC_FORCE_HARDENED_PACKET_CHECKS
-#undef FORCE_EVENT_CHECKSUM
-#define FORCE_EVENT_CHECKSUM 1
-#endif
-
-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);
-}
-
-#pragma pack(push, 1)
-struct TTcpPacketHeader_v2 {
- ui64 Confirm;
- ui64 Serial;
- ui32 Checksum; // for the whole frame
- ui16 PayloadLength;
-};
-#pragma pack(pop)
-
-struct TTcpPacketBuf {
- static constexpr ui64 PingRequestMask = 0x8000000000000000ULL;
- static constexpr ui64 PingResponseMask = 0x4000000000000000ULL;
- static constexpr ui64 ClockMask = 0x2000000000000000ULL;
-
- static constexpr size_t PacketDataLen = 4096 * 2 - 96 - sizeof(TTcpPacketHeader_v2);
-};
-
-struct TEventData {
- ui32 Type;
- ui32 Flags;
- TActorId Recipient;
- TActorId Sender;
- ui64 Cookie;
- NWilson::TTraceId TraceId;
- ui32 Checksum;
-#if IC_FORCE_HARDENED_PACKET_CHECKS
- ui32 Len;
-#endif
-};
-
-#pragma pack(push, 1)
-
-struct TEventDescr2 {
- ui32 Type;
- ui32 Flags;
- TActorId Recipient;
- TActorId Sender;
- ui64 Cookie;
- NWilson::TTraceId::TSerializedTraceId TraceId;
- ui32 Checksum;
-#if IC_FORCE_HARDENED_PACKET_CHECKS
- ui32 Len;
-#endif
-};
-
-#pragma pack(pop)
-
-struct TEventHolder : TNonCopyable {
- TEventData Descr;
- TActorId ForwardRecipient;
- THolder<IEventBase> Event;
- TIntrusivePtr<TEventSerializedData> Buffer;
- ui64 Serial;
- ui32 EventSerializedSize;
- ui32 EventActuallySerialized;
- mutable NLWTrace::TOrbit Orbit;
- NWilson::TSpan Span;
-
- ui32 Fill(IEventHandle& ev);
-
- void InitChecksum() {
- Descr.Checksum = 0;
- }
-
- void UpdateChecksum(const void *buffer, size_t len) {
- if (FORCE_EVENT_CHECKSUM) {
- Descr.Checksum = Crc32cExtendMSanCompatible(Descr.Checksum, buffer, len);
- }
- }
-
- void ForwardOnNondelivery(bool unsure) {
- TEventData& d = Descr;
- const TActorId& r = d.Recipient;
- const TActorId& s = d.Sender;
- const TActorId *f = ForwardRecipient ? &ForwardRecipient : nullptr;
- Span.EndError("nondelivery");
- auto ev = Event
- ? std::make_unique<IEventHandle>(r, s, Event.Release(), d.Flags, d.Cookie, f, Span.GetTraceId())
- : std::make_unique<IEventHandle>(d.Type, d.Flags, r, s, std::move(Buffer), d.Cookie, f, Span.GetTraceId());
- NActors::TActivationContext::Send(IEventHandle::ForwardOnNondelivery(std::move(ev), NActors::TEvents::TEvUndelivered::Disconnected, unsure));
- }
-
- void Clear() {
- Event.Reset();
- Buffer.Reset();
- Orbit.Reset();
- Span = {};
- }
-};
-
-namespace NActors {
- class TEventOutputChannel;
-}
-
-struct TTcpPacketOutTask : TNonCopyable {
- const TSessionParams& Params;
- NInterconnect::TOutgoingStream& OutgoingStream;
- NInterconnect::TOutgoingStream& XdcStream;
- NInterconnect::TOutgoingStream::TBookmark HeaderBookmark;
- ui32 InternalSize = 0;
- ui32 ExternalSize = 0;
-
- ui32 PreBookmarkChecksum = 0;
- ui32 InternalChecksum = 0;
- ui32 InternalChecksumLen = 0;
- bool InsideBookmark = false;
-
- ui32 ExternalChecksum = 0;
-
- TTcpPacketOutTask(const TSessionParams& params, NInterconnect::TOutgoingStream& outgoingStream,
- NInterconnect::TOutgoingStream& xdcStream)
- : Params(params)
- , OutgoingStream(outgoingStream)
- , XdcStream(xdcStream)
- , HeaderBookmark(OutgoingStream.Bookmark(sizeof(TTcpPacketHeader_v2)))
- {}
-
- // Preallocate some space to fill it later.
- NInterconnect::TOutgoingStream::TBookmark Bookmark(size_t len) {
- if (ChecksummingCrc32c()) {
- Y_DEBUG_ABORT_UNLESS(!InsideBookmark);
- InsideBookmark = true;
- PreBookmarkChecksum = std::exchange(InternalChecksum, 0);
- InternalChecksumLen = 0;
- }
- Y_DEBUG_ABORT_UNLESS(len <= GetInternalFreeAmount());
- InternalSize += len;
- return OutgoingStream.Bookmark(len);
- }
-
- // Write previously bookmarked space.
- void WriteBookmark(NInterconnect::TOutgoingStream::TBookmark&& bookmark, const void *buffer, size_t len) {
- if (ChecksummingCrc32c()) {
- Y_DEBUG_ABORT_UNLESS(InsideBookmark);
- InsideBookmark = false;
- const ui32 bookmarkChecksum = Crc32cExtendMSanCompatible(PreBookmarkChecksum, buffer, len);
- InternalChecksum = Crc32cCombine(bookmarkChecksum, InternalChecksum, InternalChecksumLen);
- }
- OutgoingStream.WriteBookmark(std::move(bookmark), {static_cast<const char*>(buffer), len});
- }
-
- // Acquire raw pointer to write some data.
- template<bool External>
- TMutableContiguousSpan AcquireSpanForWriting() {
- if (External) {
- return XdcStream.AcquireSpanForWriting(GetExternalFreeAmount());
- } else {
- return OutgoingStream.AcquireSpanForWriting(GetInternalFreeAmount());
- }
- }
-
- // Append reference to some data (acquired previously or external pointer).
- template<bool External>
- void Append(const void *buffer, size_t len) {
- Y_DEBUG_ABORT_UNLESS(len <= (External ? GetExternalFreeAmount() : GetInternalFreeAmount()));
- (External ? ExternalSize : InternalSize) += len;
- (External ? XdcStream : OutgoingStream).Append({static_cast<const char*>(buffer), len});
- ProcessChecksum<External>(buffer, len);
- }
-
- // Write some data with copying.
- template<bool External>
- void Write(const void *buffer, size_t len) {
- Y_DEBUG_ABORT_UNLESS(len <= (External ? GetExternalFreeAmount() : GetInternalFreeAmount()));
- (External ? ExternalSize : InternalSize) += len;
- (External ? XdcStream : OutgoingStream).Write({static_cast<const char*>(buffer), len});
- ProcessChecksum<External>(buffer, len);
- }
-
- template<bool External>
- void ProcessChecksum(const void *buffer, size_t len) {
- if (ChecksummingCrc32c()) {
- if (External) {
- ExternalChecksum = Crc32cExtendMSanCompatible(ExternalChecksum, buffer, len);
- } else {
- InternalChecksum = Crc32cExtendMSanCompatible(InternalChecksum, buffer, len);
- InternalChecksumLen += len;
- }
- }
- }
-
- void Finish(ui64 serial, ui64 confirm) {
- Y_ABORT_UNLESS(InternalSize <= Max<ui16>());
-
- TTcpPacketHeader_v2 header{
- confirm,
- serial,
- 0,
- static_cast<ui16>(InternalSize)
- };
-
- if (ChecksummingXxhash()) {
- // write header with zero checksum to calculate whole packet checksum correctly
- OutgoingStream.WriteBookmark(NInterconnect::TOutgoingStream::TBookmark(HeaderBookmark),
- {reinterpret_cast<const char*>(&header), sizeof(header)});
-
- // calculate packet checksum
- XXH3_state_t state;
- XXH3_64bits_reset(&state);
- OutgoingStream.ScanLastBytes(GetPacketSize(), [&state](TContiguousSpan span) {
- XXH3_64bits_update(&state, span.data(), span.size());
- });
- header.Checksum = XXH3_64bits_digest(&state);
- } else if (ChecksummingCrc32c()) {
- Y_DEBUG_ABORT_UNLESS(!InsideBookmark);
- const ui32 headerChecksum = Crc32cExtendMSanCompatible(0, &header, sizeof(header));
- header.Checksum = Crc32cCombine(headerChecksum, InternalChecksum, InternalSize);
- }
-
- OutgoingStream.WriteBookmark(std::exchange(HeaderBookmark, {}), {reinterpret_cast<const char*>(&header),
- sizeof(header)});
- }
-
- bool ChecksummingCrc32c() const {
- return !Params.Encryption && !Params.UseXxhash;
- }
-
- bool ChecksummingXxhash() const {
- return !Params.Encryption && Params.UseXxhash;
- }
-
- bool IsEmpty() const { return GetDataSize() == 0; }
- ui32 GetDataSize() const { return InternalSize + ExternalSize; }
- ui32 GetPacketSize() const { return sizeof(TTcpPacketHeader_v2) + InternalSize; }
- ui32 GetInternalFreeAmount() const { return TTcpPacketBuf::PacketDataLen - InternalSize; }
- ui32 GetExternalFreeAmount() const { return 16384 - ExternalSize; }
- ui32 GetExternalSize() const { return ExternalSize; }
-};
-
-namespace NInterconnect::NDetail {
- static constexpr size_t MaxNumberBytes = (sizeof(ui64) * CHAR_BIT + 6) / 7;
-
- inline size_t SerializeNumber(ui64 num, char *buffer) {
- char *begin = buffer;
- do {
- *buffer++ = (num & 0x7F) | (num >= 128 ? 0x80 : 0x00);
- num >>= 7;
- } while (num);
- return buffer - begin;
- }
-
- inline ui64 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<ui64>();
- }
- const char byte = *p++;
- res |= (static_cast<size_t>(byte) & 0x7F) << offset;
- offset += 7;
- if (!(byte & 0x80)) {
- break;
- }
- }
- *ptr = p;
- return res;
- }
-}
diff --git a/library/cpp/actors/interconnect/poller.h b/library/cpp/actors/interconnect/poller.h
deleted file mode 100644
index ff7979369f..0000000000
--- a/library/cpp/actors/interconnect/poller.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include <functional>
-#include <library/cpp/actors/core/events.h>
-
-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
deleted file mode 100644
index 040bdf8651..0000000000
--- a/library/cpp/actors/interconnect/poller_actor.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-#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>
-#include <library/cpp/actors/core/log.h>
-#include <library/cpp/actors/core/probes.h>
-#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>
-
-namespace NActors {
-
- LWTRACE_USING(ACTORLIB_PROVIDER);
-
- namespace {
- 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;
-
- 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_ABORT("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_ABORT("WriteEnd.Write() failed with %s", strerror(err));
- }
- } else {
- Y_ABORT_UNLESS(nwritten);
- break;
- }
- }
- }
- // wait for operation to complete
- wrapper.Wait();
- }
-
- void DrainReadEnd() {
- 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;
- } else {
- Y_ABORT("read() failed with %s", strerror(errno));
- }
- } else {
- Y_ABORT_UNLESS(n);
- }
- }
- }
-
- bool ProcessSyncOpQueue() {
- Y_ABORT_UNLESS(!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_ABORT();
- }
- } while (SyncOperationsQ.Pop());
- return true;
- }
-
- void *ThreadProc() override {
- SetCurrentThreadName("network poller");
- for (;;) {
- if (static_cast<TDerived&>(*this).ProcessEventsInLoop()) { // need to process the queue
- DrainReadEnd();
- if (!ProcessSyncOpQueue()) {
- break;
- }
- }
- }
- return nullptr;
- }
- };
-
-} // 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
-
-namespace NActors {
-
- 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))
- {
- thread->RegisterSocket(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, false, false);
- }
- }
-
- bool RequestReadNotificationAfterWouldBlock() {
- if (auto thread = Thread.lock()) {
- return thread->Request(Record, true, false, true, true);
- } else {
- return false;
- }
- }
-
- bool RequestWriteNotificationAfterWouldBlock() {
- if (auto thread = Thread.lock()) {
- return thread->Request(Record, false, true, true, true);
- } else {
- return false;
- }
- }
-
- const TIntrusivePtr<TSharedDescriptor>& Socket() const {
- return Record->Socket;
- }
- };
-
- class TPollerActor: public TActorBootstrapped<TPollerActor> {
- // poller thread
- std::shared_ptr<TPollerThread> PollerThread;
-
- public:
- static constexpr IActor::EActivityType ActorActivityType() {
- return IActor::EActivityType::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);
- }
-
- bool TPollerToken::RequestReadNotificationAfterWouldBlock() {
- return Impl->RequestReadNotificationAfterWouldBlock();
- }
-
- bool TPollerToken::RequestWriteNotificationAfterWouldBlock() {
- return Impl->RequestWriteNotificationAfterWouldBlock();
- }
-
- IActor* CreatePollerActor() {
- return new TPollerActor();
- }
-
-}
diff --git a/library/cpp/actors/interconnect/poller_actor.h b/library/cpp/actors/interconnect/poller_actor.h
deleted file mode 100644
index 4fb2d49a65..0000000000
--- a/library/cpp/actors/interconnect/poller_actor.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#pragma once
-
-#include "events_local.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);
- bool RequestReadNotificationAfterWouldBlock();
- bool RequestWriteNotificationAfterWouldBlock();
-
- bool RequestNotificationAfterWouldBlock(bool read, bool write) {
- bool status = false;
- status |= read && RequestReadNotificationAfterWouldBlock();
- status |= write && RequestWriteNotificationAfterWouldBlock();
- return status;
- }
-
- 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
deleted file mode 100644
index cd763ac589..0000000000
--- a/library/cpp/actors/interconnect/poller_actor_darwin.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#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_ABORT_UNLESS(rc != -1, "kevent() failed with %s", strerror(errno));
- }
-
- public:
- TKqueueThread(TActorSystem *actorSystem)
- : TPollerThreadBase(actorSystem)
- {
- // create kqueue
- KqDescriptor = kqueue();
- Y_ABORT_UNLESS(KqDescriptor != -1, "kqueue() failed with %s", strerror(errno));
-
- // set close-on-exit flag
- {
- int flags = fcntl(KqDescriptor, F_GETFD);
- Y_ABORT_UNLESS(flags >= 0, "fcntl(F_GETFD) failed with %s", strerror(errno));
- int rc = fcntl(KqDescriptor, F_SETFD, flags | FD_CLOEXEC);
- Y_ABORT_UNLESS(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);
- }
-
- bool 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 false;
- } else {
- Y_ABORT("kevent() failed with %s", strerror(errno));
- }
- }
-
- bool res = false;
-
- 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);
- } else {
- res = true;
- }
- }
-
- return res;
- }
-
- 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);
- }
-
- bool Request(const TIntrusivePtr<TSocketRecord>& /*socket*/, bool /*read*/, bool /*write*/, bool /*suppressNotify*/,
- bool /*afterWouldBlock*/) {
- return false; // 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
deleted file mode 100644
index 2cd557e347..0000000000
--- a/library/cpp/actors/interconnect/poller_actor_linux.h
+++ /dev/null
@@ -1,132 +0,0 @@
-#pragma once
-
-#include <sys/epoll.h>
-
-namespace NActors {
-
- enum {
- ReadExpected = 1,
- ReadHit = 2,
- WriteExpected = 4,
- WriteHit = 8,
- };
-
- class TEpollThread : public TPollerThreadBase<TEpollThread> {
- // epoll file descriptor
- int EpollDescriptor;
-
- public:
- TEpollThread(TActorSystem *actorSystem)
- : TPollerThreadBase(actorSystem)
- {
- EpollDescriptor = epoll_create1(EPOLL_CLOEXEC);
- Y_ABORT_UNLESS(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_ABORT("epoll_ctl(EPOLL_CTL_ADD) failed with %s", strerror(errno));
- }
-
- ISimpleThread::Start(); // start poller thread
- }
-
- ~TEpollThread() {
- Stop();
- close(EpollDescriptor);
- }
-
- bool 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 false; // restart the call a bit later
- } else {
- Y_ABORT("epoll_wait() failed with %s", strerror(errno));
- }
- }
-
- bool res = false;
-
- 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);
- UpdateFlags(record, (read ? ReadHit : 0) | (write ? WriteHit : 0), false /*suppressNotify*/,
- false /*checkQueues*/);
- } else {
- res = true;
- }
- }
-
- return res;
- }
-
- bool UpdateFlags(TSocketRecord *record, ui32 addMask, bool suppressNotify, bool checkQueues) {
- ui32 flags = record->Flags.load(std::memory_order_acquire);
- for (;;) {
- ui32 updated = flags | addMask;
- static constexpr ui32 fullRead = ReadExpected | ReadHit;
- static constexpr ui32 fullWrite = WriteExpected | WriteHit;
- bool read = (updated & fullRead) == fullRead;
- bool write = (updated & fullWrite) == fullWrite;
- updated &= ~((read ? fullRead : 0) | (write ? fullWrite : 0));
- if (record->Flags.compare_exchange_weak(flags, updated, std::memory_order_acq_rel)) {
- if (suppressNotify) {
- return read || write;
- } else {
- if (checkQueues) {
- pollfd fd;
- fd.fd = record->Socket->GetDescriptor();
- const bool queryRead = updated & ReadExpected && !read;
- const bool queryWrite = updated & WriteExpected && !write;
- if (queryRead || queryWrite) {
- fd.events = (queryRead ? POLLIN : 0) | (queryWrite ? POLLOUT : 0);
- if (poll(&fd, 1, 0) != -1) {
- read = queryRead && fd.revents & (POLLIN | POLLHUP | POLLRDHUP | POLLERR);
- write = queryWrite && fd.revents & (POLLOUT | POLLERR);
- }
- }
- }
- Notify(record, read, write);
- return false;
- }
- }
- }
- }
-
- void UnregisterSocketInLoop(const TIntrusivePtr<TSharedDescriptor>& socket) {
- if (epoll_ctl(EpollDescriptor, EPOLL_CTL_DEL, socket->GetDescriptor(), nullptr) == -1) {
- Y_ABORT("epoll_ctl(EPOLL_CTL_DEL) failed with %s", strerror(errno));
- }
- }
-
- void RegisterSocket(const TIntrusivePtr<TSocketRecord>& record) {
- epoll_event event;
- event.events = EPOLLET | EPOLLRDHUP | EPOLLIN | EPOLLOUT;
- event.data.ptr = record.Get();
- if (epoll_ctl(EpollDescriptor, EPOLL_CTL_ADD, record->Socket->GetDescriptor(), &event) == -1) {
- Y_ABORT("epoll_ctl(EPOLL_CTL_ADD) failed with %s", strerror(errno));
- }
- }
-
- bool Request(const TIntrusivePtr<TSocketRecord>& record, bool read, bool write, bool suppressNotify,
- bool afterWouldBlock) {
- return UpdateFlags(record.Get(), (read ? ReadExpected : 0) | (write ? WriteExpected : 0), suppressNotify,
- !afterWouldBlock);
- }
- };
-
- 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
deleted file mode 100644
index a4b213ff8c..0000000000
--- a/library/cpp/actors/interconnect/poller_actor_win.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#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();
- }
-
- bool 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 false; // try a bit later
- } else {
- Y_ABORT("select() failed with %s", strerror(err));
- }
- }
-
- bool flag = false;
-
- 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);
- } else {
- flag = true;
- }
- }
- }
-
- return flag;
- }
-
- 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());
- }
-
- bool Request(const TIntrusivePtr<TSocketRecord>& record, bool read, bool write, bool /*suppressNotify*/,
- bool /*afterWouldBlock*/) {
- with_lock (Mutex) {
- const auto it = Descriptors.find(record->Socket->GetDescriptor());
- Y_ABORT_UNLESS(it != Descriptors.end());
- it->second->Flags |= (read ? READ : 0) | (write ? WRITE : 0);
- }
- ExecuteSyncOperation(TPollerWakeup());
- return false;
- }
- };
-
- using TPollerThread = TSelectThread;
-
-} // NActors
diff --git a/library/cpp/actors/interconnect/poller_tcp.cpp b/library/cpp/actors/interconnect/poller_tcp.cpp
deleted file mode 100644
index ab9b7c85ea..0000000000
--- a/library/cpp/actors/interconnect/poller_tcp.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "poller_tcp.h"
-
-namespace NInterconnect {
- TPollerThreads::TPollerThreads(size_t units, bool useSelect)
- : Units(units)
- {
- Y_DEBUG_ABORT_UNLESS(!Units.empty());
- 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
deleted file mode 100644
index 310265eccd..0000000000
--- a/library/cpp/actors/interconnect/poller_tcp.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#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
deleted file mode 100644
index 994d907004..0000000000
--- a/library/cpp/actors/interconnect/poller_tcp_unit.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-#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"
-
-#include <library/cpp/actors/prof/tag.h>
-#include <library/cpp/actors/util/intrinsics.h>
-
-#if defined _linux_
-#include <pthread.h>
-#endif
-
-namespace NInterconnect {
- TPollerUnit::TPtr
- TPollerUnit::Make(bool useSelect) {
-#if defined(_win_) || defined(_darwin_)
- Y_UNUSED(useSelect);
- return TPtr(new TPollerUnitSelect);
-#else
- return useSelect ? TPtr(new TPollerUnitSelect) : TPtr(new TPollerUnitEpoll);
-#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,
- TFDDelegate&& operation) {
- Y_DEBUG_ABORT_UNLESS(stream);
- if (AtomicLoad(&StopFlag))
- return;
- GetSide<false>().InputQueue.Push(TSide::TItem(stream, std::move(operation)));
- }
-
- void
- TPollerUnit::StartWriteOperation(
- const TIntrusivePtr<TSharedDescriptor>& stream,
- TFDDelegate&& operation) {
- Y_DEBUG_ABORT_UNLESS(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
-#if defined(_linux_) && !defined(_musl_)
- pthread_t threadSelf = pthread_self();
- sched_param sparam = {20};
- pthread_setschedparam(threadSelf, SCHED_FIFO, &sparam);
-#endif
-
- static_cast<TPollerUnit*>(param)->RunLoop<IsWrite>();
- return nullptr;
- }
-
- template <>
- void
- TPollerUnit::RunLoop<false>() {
- NProfiling::TMemoryTagScope tag("INTERCONNECT_RECEIVED_DATA");
- while (!AtomicLoad(&StopFlag))
- ProcessRead();
- }
-
- template <>
- void
- TPollerUnit::RunLoop<true>() {
- NProfiling::TMemoryTagScope tag("INTERCONNECT_SEND_DATA");
- while (!AtomicLoad(&StopFlag))
- ProcessWrite();
- }
-
- void
- TPollerUnit::TSide::ProcessInput() {
- if (!InputQueue.IsEmpty())
- do {
- auto sock = InputQueue.Top().first->GetDescriptor();
- if (!Operations.emplace(sock, std::move(InputQueue.Top())).second)
- Y_ABORT("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
deleted file mode 100644
index 692168b968..0000000000
--- a/library/cpp/actors/interconnect/poller_tcp_unit.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#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 {
- 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
deleted file mode 100644
index aac6d52bb4..0000000000
--- a/library/cpp/actors/interconnect/poller_tcp_unit_epoll.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-#include "poller_tcp_unit_epoll.h"
-#if !defined(_win_) && !defined(_darwin_)
-#include <unistd.h>
-#include <sys/epoll.h>
-
-#include <csignal>
-#include <cerrno>
-
-namespace NInterconnect {
- namespace {
- void
- DeleteEpoll(int epoll, SOCKET stream) {
- ::epoll_event event = {0, {.fd = stream}};
- if (::epoll_ctl(epoll, EPOLL_CTL_DEL, stream, &event)) {
- Cerr << "epoll_ctl errno: " << errno << Endl;
- Y_ABORT("epoll delete error!");
- }
- }
-
- template <ui32 Events>
- void
- AddEpoll(int epoll, SOCKET stream) {
- ::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_ABORT("epoll add error!");
- }
- }
-
- int
- Initialize() {
- const auto epoll = ::epoll_create(10000);
- Y_DEBUG_ABORT_UNLESS(epoll > 0);
- return epoll;
- }
-
- }
-
- TPollerUnitEpoll::TPollerUnitEpoll()
- : ReadDescriptor(Initialize())
- , WriteDescriptor(Initialize())
- {
- // Block on the epoll descriptor.
- ::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,
- TFDDelegate&& operation) {
- TPollerUnit::StartReadOperation(s, std::move(operation));
- AddEpoll<EPOLLRDHUP | EPOLLIN>(ReadDescriptor, s->GetDescriptor());
- }
-
- void
- TPollerUnitEpoll::StartWriteOperation(
- 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_ABORT("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)
- continue;
- if (const auto& finalizer = it->second.second(it->second.first)) {
- DeleteEpoll(epoll, it->first);
- side.Operations.erase(it);
- finalizer();
- }
- }
- }
-
- void
- TPollerUnitEpoll::ProcessRead() {
- Process<false>();
- }
-
- void
- TPollerUnitEpoll::ProcessWrite() {
- Process<true>();
- }
-
-}
-
-#endif
diff --git a/library/cpp/actors/interconnect/poller_tcp_unit_epoll.h b/library/cpp/actors/interconnect/poller_tcp_unit_epoll.h
deleted file mode 100644
index ff7893eba2..0000000000
--- a/library/cpp/actors/interconnect/poller_tcp_unit_epoll.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#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
deleted file mode 100644
index 1615d4679d..0000000000
--- a/library/cpp/actors/interconnect/poller_tcp_unit_select.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#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_)
- ::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_)
- ::TIMEVAL timeout = {0L, 99991L};
- const auto numberEvents = ::select(FD_SETSIZE, &sets[R], &sets[W], &sets[E], &timeout);
-#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
-
- Y_DEBUG_ABORT_UNLESS(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)) {
- side.Operations.erase(it++);
- finalizer();
- continue;
- }
- ++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
deleted file mode 100644
index 0c15217796..0000000000
--- a/library/cpp/actors/interconnect/poller_tcp_unit_select.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#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
deleted file mode 100644
index 11dac077ea..0000000000
--- a/library/cpp/actors/interconnect/profiler.h
+++ /dev/null
@@ -1,142 +0,0 @@
-#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
- 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,
- 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_ABORT_UNLESS(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_ABORT_UNLESS(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_ABORT_UNLESS(it != Items.end());
- Y_ABORT_UNLESS(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 << "}";
- }
- }
- }
-
- return s.Str();
- }
- };
-
-} // NActors
diff --git a/library/cpp/actors/interconnect/slowpoke_actor.h b/library/cpp/actors/interconnect/slowpoke_actor.h
deleted file mode 100644
index 4b02e5da48..0000000000
--- a/library/cpp/actors/interconnect/slowpoke_actor.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#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:
- 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
diff --git a/library/cpp/actors/interconnect/types.cpp b/library/cpp/actors/interconnect/types.cpp
deleted file mode 100644
index 979c55f277..0000000000
--- a/library/cpp/actors/interconnect/types.cpp
+++ /dev/null
@@ -1,564 +0,0 @@
-#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
deleted file mode 100644
index 14b1a1c7a6..0000000000
--- a/library/cpp/actors/interconnect/types.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/defs.h>
-#include <library/cpp/actors/core/actorid.h>
-#include <library/cpp/actors/core/event.h>
-
-#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;
- }
-
- friend bool operator ==(const TDisconnectReason& x, const TDisconnectReason& y) { return x.Text == y.Text; }
-
- static TVector<const char*> Reasons;
- };
-
- struct TProgramInfo {
- ui64 PID = 0;
- ui64 StartTime = 0;
- ui64 Serial = 0;
- };
-
- struct TSessionParams {
- bool Encryption = {};
- bool AuthOnly = {};
- bool UseExternalDataChannel = {};
- bool UseXxhash = {};
- bool UseXdcShuffle = {};
- TString AuthCN;
- NActors::TScopeId PeerScopeId;
- };
-
-} // NActors
-
-using NActors::IEventBase;
-using NActors::IEventHandle;
-using NActors::TActorId;
-using NActors::TConstIoVec;
-using NActors::TEventSerializedData;
-using NActors::TSessionParams;
diff --git a/library/cpp/actors/interconnect/ut/CMakeLists.darwin-arm64.txt b/library/cpp/actors/interconnect/ut/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 0b2d5cfe5c..0000000000
--- a/library/cpp/actors/interconnect/ut/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,85 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(lib)
-add_subdirectory(protos)
-
-add_executable(library-cpp-actors-interconnect-ut)
-target_link_libraries(library-cpp-actors-interconnect-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-actors-testlib
- cpp-digest-md5
- cpp-testing-unittest
-)
-target_link_options(library-cpp-actors-interconnect-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-interconnect-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/interconnect_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/large.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/outgoing_stream_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/sticking_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut
- TEST_TARGET
- library-cpp-actors-interconnect-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-interconnect-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-interconnect-ut)
diff --git a/library/cpp/actors/interconnect/ut/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/interconnect/ut/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 7519ee7ba9..0000000000
--- a/library/cpp/actors/interconnect/ut/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,86 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(lib)
-add_subdirectory(protos)
-
-add_executable(library-cpp-actors-interconnect-ut)
-target_link_libraries(library-cpp-actors-interconnect-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-actors-testlib
- cpp-digest-md5
- cpp-testing-unittest
-)
-target_link_options(library-cpp-actors-interconnect-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-interconnect-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/interconnect_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/large.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/outgoing_stream_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/sticking_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut
- TEST_TARGET
- library-cpp-actors-interconnect-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-interconnect-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-interconnect-ut)
diff --git a/library/cpp/actors/interconnect/ut/CMakeLists.linux-aarch64.txt b/library/cpp/actors/interconnect/ut/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 1d488c4550..0000000000
--- a/library/cpp/actors/interconnect/ut/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(lib)
-add_subdirectory(protos)
-
-add_executable(library-cpp-actors-interconnect-ut)
-target_link_libraries(library-cpp-actors-interconnect-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-actors-testlib
- cpp-digest-md5
- cpp-testing-unittest
-)
-target_link_options(library-cpp-actors-interconnect-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-interconnect-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/interconnect_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/large.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/outgoing_stream_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/sticking_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut
- TEST_TARGET
- library-cpp-actors-interconnect-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-interconnect-ut
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-interconnect-ut)
diff --git a/library/cpp/actors/interconnect/ut/CMakeLists.linux-x86_64.txt b/library/cpp/actors/interconnect/ut/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 3ee5b5f656..0000000000
--- a/library/cpp/actors/interconnect/ut/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,91 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(lib)
-add_subdirectory(protos)
-
-add_executable(library-cpp-actors-interconnect-ut)
-target_link_libraries(library-cpp-actors-interconnect-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-actors-testlib
- cpp-digest-md5
- cpp-testing-unittest
-)
-target_link_options(library-cpp-actors-interconnect-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-interconnect-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/interconnect_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/large.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/outgoing_stream_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/sticking_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut
- TEST_TARGET
- library-cpp-actors-interconnect-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-interconnect-ut
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-interconnect-ut)
diff --git a/library/cpp/actors/interconnect/ut/CMakeLists.txt b/library/cpp/actors/interconnect/ut/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/interconnect/ut/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/interconnect/ut/CMakeLists.windows-x86_64.txt b/library/cpp/actors/interconnect/ut/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index b928771974..0000000000
--- a/library/cpp/actors/interconnect/ut/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(lib)
-add_subdirectory(protos)
-
-add_executable(library-cpp-actors-interconnect-ut)
-target_link_libraries(library-cpp-actors-interconnect-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-actors-testlib
- cpp-digest-md5
- cpp-testing-unittest
-)
-target_sources(library-cpp-actors-interconnect-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/interconnect_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/large.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/outgoing_stream_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/sticking_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut
- TEST_TARGET
- library-cpp-actors-interconnect-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- PROCESSORS
- 1
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-interconnect-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-interconnect-ut)
diff --git a/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp b/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp
deleted file mode 100644
index 98e81d7781..0000000000
--- a/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-#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>();
- std::shared_ptr<IInterconnectMetrics> ctr = CreateInterconnectCounters(common);
- ctr->SetPeerInfo("peer", "1");
- 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');
- auto ev = MakeHolder<IEventHandle>(1, 0, TActorId(), TActorId(), MakeIntrusive<TEventSerializedData>(payload, TEventSerializationInfo{}), 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;
-
- NInterconnect::TOutgoingStream stream;
-
- for (; numEvents; ++step) {
- TTcpPacketOutTask task(p, stream, stream);
-
- 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_ABORT_UNLESS(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
deleted file mode 100644
index 4cc6a3cc99..0000000000
--- a/library/cpp/actors/interconnect/ut/dynamic_proxy_ut.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-#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_ABORT_UNLESS(index == expected);
- ++expected;
- }
- for (const ui32 index : st.Error) {
- Y_ABORT_UNLESS(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_ABORT_UNLESS(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
deleted file mode 100644
index 7b45793e26..0000000000
--- a/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <library/cpp/testing/unittest/registar.h>
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/actors/core/event_local.h>
-#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>();
- 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), TEventSerializationInfo{});
-
- auto& ev2 = pool.Allocate(q);
- ev2.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), TEventSerializationInfo{});
-
- auto& ev3 = pool.Allocate(q);
- ev3.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), TEventSerializationInfo{});
-
- auto& ev4 = pool.Allocate(q);
- ev4.Buffer = MakeIntrusive<TEventSerializedData>(TString::Uninitialized(512 * 1024), TEventSerializationInfo{});
-
- 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
deleted file mode 100644
index bc9e86545a..0000000000
--- a/library/cpp/actors/interconnect/ut/interconnect_ut.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-#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_ABORT_UNLESS(!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), TEventSerializationInfo{}), 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_ABORT_UNLESS(hash == ev->GetChainBuffer()->GetString());
- SessionToCookie.erase(s2cIt);
- InFlight.erase(it);
- } else if (const auto it = Tentative.find(ev->Cookie); it != Tentative.end()) {
- Y_ABORT_UNLESS(it->second == ev->GetChainBuffer()->GetString());
- Tentative.erase(it);
- } else {
- Y_ABORT("Cookie# %" PRIu64, ev->Cookie);
- }
- IssueQueries();
- }
-
- void Handle(TEvInterconnect::TEvNodeConnected::TPtr ev) {
- Cerr << (TStringBuilder() << "TEvNodeConnected" << Endl);
- Y_ABORT_UNLESS(SubscribeInFlight);
- SubscribeInFlight = false;
- Y_ABORT_UNLESS(!SessionId);
- SessionId = ev->Sender;
- IssueQueries();
- }
-
- void Handle(TEvInterconnect::TEvNodeDisconnected::TPtr ev) {
- Cerr << (TStringBuilder() << "TEvNodeDisconnected" << Endl);
- SubscribeInFlight = false;
- if (SessionId) {
- Y_ABORT_UNLESS(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_ABORT_UNLESS(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, TEventSerializationInfo{}), 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_ABORT();
- }
-
- 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
deleted file mode 100644
index 88207f816b..0000000000
--- a/library/cpp/actors/interconnect/ut/large.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-#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> {
- const TActorId RecipientActorId;
-
- 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(150 * 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_ABORT_UNLESS(!SessionId);
- SessionId = ev->InterconnectSession;
- } else if (record.GetSequenceNumber() == 3) {
- Y_ABORT_UNLESS(SessionId != ev->InterconnectSession);
- Done.Signal();
- } else {
- Y_ABORT("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();
- }
-
-}
diff --git a/library/cpp/actors/interconnect/ut/lib/CMakeLists.darwin-arm64.txt b/library/cpp/actors/interconnect/ut/lib/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index a6a86ac09b..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(interconnect-ut-lib INTERFACE)
-target_link_libraries(interconnect-ut-lib INTERFACE
- contrib-libs-cxxsupp
- yutil
-)
diff --git a/library/cpp/actors/interconnect/ut/lib/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/interconnect/ut/lib/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index a6a86ac09b..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(interconnect-ut-lib INTERFACE)
-target_link_libraries(interconnect-ut-lib INTERFACE
- contrib-libs-cxxsupp
- yutil
-)
diff --git a/library/cpp/actors/interconnect/ut/lib/CMakeLists.linux-aarch64.txt b/library/cpp/actors/interconnect/ut/lib/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index b20c3b0de9..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(interconnect-ut-lib INTERFACE)
-target_link_libraries(interconnect-ut-lib INTERFACE
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
-)
diff --git a/library/cpp/actors/interconnect/ut/lib/CMakeLists.linux-x86_64.txt b/library/cpp/actors/interconnect/ut/lib/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index b20c3b0de9..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(interconnect-ut-lib INTERFACE)
-target_link_libraries(interconnect-ut-lib INTERFACE
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
-)
diff --git a/library/cpp/actors/interconnect/ut/lib/CMakeLists.txt b/library/cpp/actors/interconnect/ut/lib/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/interconnect/ut/lib/CMakeLists.windows-x86_64.txt b/library/cpp/actors/interconnect/ut/lib/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index a6a86ac09b..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(interconnect-ut-lib INTERFACE)
-target_link_libraries(interconnect-ut-lib INTERFACE
- contrib-libs-cxxsupp
- yutil
-)
diff --git a/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h b/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h
deleted file mode 100644
index dd2557e25e..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#pragma once
-
-#include "node.h"
-#include "interrupter.h"
-
-#include <library/cpp/actors/interconnect/interconnect_tcp_proxy.h>
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/testing/unittest/tests_data.h>
-
-#include <util/generic/noncopyable.h>
-
-class TTestICCluster: public TNonCopyable {
-public:
- struct TTrafficInterrupterSettings {
- TDuration RejectingTrafficTimeout;
- double BandWidth;
- bool Disconnect;
- };
-
-private:
- const ui32 NumNodes;
- const TString Address = "::1";
- TDuration DeadPeerTimeout = TDuration::Seconds(2);
- NMonitoring::TDynamicCounterPtr Counters;
- THashMap<ui32, THolder<TNode>> Nodes;
- TList<TTrafficInterrupter> interrupters;
- NActors::TChannelsConfig ChannelsConfig;
- TPortManager PortManager;
- TIntrusivePtr<NLog::TSettings> LoggerSettings;
-
-public:
- TTestICCluster(ui32 numNodes = 1, NActors::TChannelsConfig channelsConfig = NActors::TChannelsConfig(),
- TTrafficInterrupterSettings* tiSettings = nullptr, TIntrusivePtr<NLog::TSettings> loggerSettings = nullptr)
- : NumNodes(numNodes)
- , Counters(new NMonitoring::TDynamicCounters)
- , ChannelsConfig(channelsConfig)
- , LoggerSettings(loggerSettings)
- {
- THashMap<ui32, ui16> nodeToPortMap;
- THashMap<ui32, THashMap<ui32, ui16>> specificNodePortMap;
-
- for (ui32 i = 1; i <= NumNodes; ++i) {
- nodeToPortMap.emplace(i, PortManager.GetPort());
- }
-
- if (tiSettings) {
- ui32 nodeId;
- ui16 listenPort;
- ui16 forwardPort;
- for (auto& item : nodeToPortMap) {
- nodeId = item.first;
- listenPort = item.second;
- forwardPort = PortManager.GetPort();
-
- specificNodePortMap[nodeId] = nodeToPortMap;
- specificNodePortMap[nodeId].at(nodeId) = forwardPort;
- interrupters.emplace_back(Address, listenPort, forwardPort, tiSettings->RejectingTrafficTimeout, tiSettings->BandWidth, tiSettings->Disconnect);
- interrupters.back().Start();
- }
- }
-
- 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,
- /*numDynamicNodes=*/0, /*numThreads=*/1, LoggerSettings));
- }
- }
-
- TNode* GetNode(ui32 id) {
- return Nodes[id].Get();
- }
-
- ~TTestICCluster() {
- }
-
- TActorId RegisterActor(NActors::IActor* actor, ui32 nodeId) {
- return Nodes[nodeId]->RegisterActor(actor);
- }
-
- 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
deleted file mode 100644
index b00985573a..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/interrupter.h
+++ /dev/null
@@ -1,249 +0,0 @@
-#pragma once
-
-#include <library/cpp/testing/unittest/tests_data.h>
-
-#include <util/network/sock.h>
-#include <util/network/poller.h>
-#include <util/system/thread.h>
-#include <util/system/hp_timer.h>
-#include <util/generic/list.h>
-#include <util/generic/set.h>
-#include <util/generic/vector.h>
-#include <util/generic/deque.h>
-#include <util/random/random.h>
-
-#include <iterator>
-
-class TTrafficInterrupter
- : public ISimpleThread {
- const TString Address;
- const ui16 ForwardPort;
- TInet6StreamSocket ListenSocket;
-
- struct TConnectionDescriptor;
- struct TDelayedPacket {
- TInet6StreamSocket* ForwardSocket = nullptr;
- TVector<char> Data;
- };
- struct TCompare {
- bool operator()(const std::pair<TInstant, TDelayedPacket>& x, const std::pair<TInstant, TDelayedPacket>& y) const {
- return x.first > y.first;
- };
- };
-
- struct TDirectedConnection {
- TInet6StreamSocket* Source = nullptr;
- TInet6StreamSocket* Destination = nullptr;
- TList<TConnectionDescriptor>::iterator ListIterator;
- TInstant Timestamp;
- TPriorityQueue<std::pair<TInstant, TDelayedPacket>, TVector<std::pair<TInstant, TDelayedPacket>>, TCompare> DelayedQueue;
-
- TDirectedConnection(TInet6StreamSocket* source, TInet6StreamSocket* destination)
- : Source(source)
- , Destination(destination)
- {
- }
- };
-
- struct TConnectionDescriptor {
- std::unique_ptr<TInet6StreamSocket> FirstSocket;
- std::unique_ptr<TInet6StreamSocket> SecondSocket;
- TDirectedConnection ForwardConnection;
- TDirectedConnection BackwardConnection;
-
- TConnectionDescriptor(std::unique_ptr<TInet6StreamSocket> firstSock,
- std::unique_ptr<TInet6StreamSocket> secondSock)
- : FirstSocket(std::move(firstSock))
- , SecondSocket(std::move(secondSock))
- , ForwardConnection(FirstSocket.get(), SecondSocket.get())
- , BackwardConnection(SecondSocket.get(), FirstSocket.get())
- {
- }
- };
-
- template <class It = TList<TConnectionDescriptor>::iterator>
- class TCustomListIteratorCompare {
- public:
- bool operator()(const It& it1, const It& it2) const {
- return (&(*it1) < &(*it2));
- }
- };
-
- TList<TConnectionDescriptor> Connections;
- TSet<TList<TConnectionDescriptor>::iterator, TCustomListIteratorCompare<>> DroppedConnections;
-
-public:
- TTrafficInterrupter(TString address, ui16 listenPort, ui16 forwardPort, TDuration rejectingTrafficTimeout, double bandwidth, bool disconnect = true)
- : Address(std::move(address))
- , ForwardPort(forwardPort)
- , ListenSocket()
- , RejectingTrafficTimeout(rejectingTrafficTimeout)
- , CurrentRejectingTimeout(rejectingTrafficTimeout)
- , RejectingStateTimer()
- , Bandwidth(bandwidth)
- , Disconnect(disconnect)
- , RejectingTraffic(false)
- {
- SetReuseAddressAndPort(ListenSocket);
- TSockAddrInet6 addr(Address.data(), listenPort);
- Y_ABORT_UNLESS(ListenSocket.Bind(&addr) == 0);
- Y_ABORT_UNLESS(ListenSocket.Listen(5) == 0);
-
- DelayTraffic = (Bandwidth == 0.0) ? false : true;
-
- ForwardAddrress.Reset(new TSockAddrInet6(Address.data(), ForwardPort));
- const ui32 BufSize = DelayTraffic ? 4096 : 65536 + 4096;
- Buf.resize(BufSize);
- }
-
- ~TTrafficInterrupter() {
- AtomicSet(Running, 0);
- this->Join();
- }
-
-private:
- TAtomic Running = 1;
- TVector<char> Buf;
- TSocketPoller SocketPoller;
- THolder<TSockAddrInet6> ForwardAddrress;
- TVector<void*> Events;
- TDuration RejectingTrafficTimeout;
- TDuration CurrentRejectingTimeout;
- TDuration DefaultPollTimeout = TDuration::MilliSeconds(100);
- TDuration DisconnectTimeout = TDuration::MilliSeconds(100);
- THPTimer RejectingStateTimer;
- THPTimer DisconnectTimer;
- double Bandwidth;
- const bool Disconnect;
- bool RejectingTraffic;
- bool DelayTraffic;
-
- void UpdateRejectingState() {
- if (TDuration::Seconds(std::abs(RejectingStateTimer.Passed())) > CurrentRejectingTimeout) {
- RejectingStateTimer.Reset();
- CurrentRejectingTimeout = (RandomNumber<ui32>(1) ? RejectingTrafficTimeout + TDuration::Seconds(1.0) : RejectingTrafficTimeout - TDuration::Seconds(0.2));
- RejectingTraffic = !RejectingTraffic;
- }
- }
-
- void RandomlyDisconnect() {
- if (TDuration::Seconds(std::abs(DisconnectTimer.Passed())) > DisconnectTimeout) {
- DisconnectTimer.Reset();
- if (RandomNumber<ui32>(100) > 90) {
- if (!Connections.empty()) {
- auto it = Connections.begin();
- std::advance(it, RandomNumber<ui32>(Connections.size()));
- SocketPoller.Unwait(static_cast<SOCKET>(*it->FirstSocket.get()));
- SocketPoller.Unwait(static_cast<SOCKET>(*it->SecondSocket.get()));
- Connections.erase(it);
- }
- }
- }
- }
-
- void* ThreadProc() override {
- int pollReadyCount = 0;
- SocketPoller.WaitRead(static_cast<SOCKET>(ListenSocket), &ListenSocket);
- Events.resize(10);
-
- while (AtomicGet(Running)) {
- if (RejectingTrafficTimeout != TDuration::Zero()) {
- UpdateRejectingState();
- }
- if (Disconnect) {
- RandomlyDisconnect();
- }
- if (!RejectingTraffic) {
- TDuration timeout = DefaultPollTimeout;
- auto updateTimout = [&timeout](TDirectedConnection& conn) {
- if (conn.DelayedQueue) {
- timeout = Min(timeout, conn.DelayedQueue.top().first - TInstant::Now());
- }
- };
- 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++) {
- HandleSocketPollEvent(Events[i]);
- }
- for (auto it : DroppedConnections) {
- Connections.erase(it);
- }
- DroppedConnections.clear();
- }
- }
- if (DelayTraffic) { // process packets from DelayQueues
- auto processDelayedPackages = [](TDirectedConnection& conn) {
- while (!conn.DelayedQueue.empty()) {
- auto& frontPackage = conn.DelayedQueue.top();
- if (TInstant::Now() >= frontPackage.first) {
- TInet6StreamSocket* sock = frontPackage.second.ForwardSocket;
- if (sock) {
- sock->Send(frontPackage.second.Data.data(), frontPackage.second.Data.size());
- }
- conn.DelayedQueue.pop();
- } else {
- break;
- }
- }
- };
- for (auto& it : Connections) {
- processDelayedPackages(it.ForwardConnection);
- processDelayedPackages(it.BackwardConnection);
- }
- }
- }
- ListenSocket.Close();
- return nullptr;
- }
-
- void HandleSocketPollEvent(void* ev) {
- if (ev == static_cast<void*>(&ListenSocket)) {
- TSockAddrInet6 origin;
- Connections.emplace_back(TConnectionDescriptor(std::unique_ptr<TInet6StreamSocket>(new TInet6StreamSocket), std::unique_ptr<TInet6StreamSocket>(new TInet6StreamSocket)));
- int err = ListenSocket.Accept(Connections.back().FirstSocket.get(), &origin);
- if (!err) {
- err = Connections.back().SecondSocket->Connect(ForwardAddrress.Get());
- if (!err) {
- Connections.back().ForwardConnection.ListIterator = --Connections.end();
- Connections.back().BackwardConnection.ListIterator = --Connections.end();
- SocketPoller.WaitRead(static_cast<SOCKET>(*Connections.back().FirstSocket), &Connections.back().ForwardConnection);
- SocketPoller.WaitRead(static_cast<SOCKET>(*Connections.back().SecondSocket), &Connections.back().BackwardConnection);
- } else {
- Connections.back().FirstSocket->Close();
- }
- } else {
- Connections.pop_back();
- }
- } else {
- TDirectedConnection* directedConnection = static_cast<TDirectedConnection*>(ev);
- int recvSize = 0;
- do {
- recvSize = directedConnection->Source->Recv(Buf.data(), Buf.size());
- } while (recvSize == -EINTR);
-
- if (recvSize > 0) {
- 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);
- memcpy(pkt.Data.data(), Buf.data(), recvSize);
- directedConnection->DelayedQueue.emplace(directedConnection->Timestamp, std::move(pkt));
- } else {
- directedConnection->Destination->Send(Buf.data(), recvSize);
- }
- } else {
- SocketPoller.Unwait(static_cast<SOCKET>(*directedConnection->Source));
- SocketPoller.Unwait(static_cast<SOCKET>(*directedConnection->Destination));
- DroppedConnections.emplace(directedConnection->ListIterator);
- }
- }
- }
-};
diff --git a/library/cpp/actors/interconnect/ut/lib/node.h b/library/cpp/actors/interconnect/ut/lib/node.h
deleted file mode 100644
index e63a95c31b..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/node.h
+++ /dev/null
@@ -1,149 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actorsystem.h>
-#include <library/cpp/actors/core/executor_pool_basic.h>
-#include <library/cpp/actors/core/executor_pool_io.h>
-#include <library/cpp/actors/core/scheduler_basic.h>
-#include <library/cpp/actors/core/mailbox.h>
-#include <library/cpp/actors/dnsresolver/dnsresolver.h>
-
-#include <library/cpp/actors/interconnect/handshake_broker.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;
-
-class TNode {
- 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,
- TIntrusivePtr<NLog::TSettings> loggerSettings = nullptr, ui32 inflight = 512 * 1024) {
- TActorSystemSetup setup;
- setup.NodeId = nodeId;
- setup.ExecutorsCount = 2;
- setup.Executors.Reset(new TAutoPtr<IExecutorPool>[setup.ExecutorsCount]);
- setup.Executors[0].Reset(new TBasicExecutorPool(0, numThreads, 20 /* magic number */));
- setup.Executors[1].Reset(new TIOExecutorPool(1, 1));
- setup.Scheduler.Reset(new TBasicSchedulerThread());
- const ui32 interconnectPoolId = 0;
-
- 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 = inflight;
- common->Settings.TCPSocketBufferSize = 2048 * 1024;
- common->OutgoingHandshakeInflightLimit = 3;
-
- 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) {
- // create proxy actor to reach node "i"
- setup.Interconnect.ProxyActors[i] = {new TInterconnectProxyTCP(i, common),
- TMailboxType::ReadAsFilled, interconnectPoolId};
- }
- }
-
- setup.LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(),
- TMailboxType::ReadAsFilled, 0));
-
- const TActorId loggerActorId = loggerSettings ? loggerSettings->LoggerActorId : TActorId(0, "logger");
-
- if (!loggerSettings) {
- constexpr ui32 LoggerComponentId = NActorsServices::LOGGER;
- loggerSettings = MakeIntrusive<NLog::TSettings>(
- loggerActorId,
- (NLog::EComponent)LoggerComponentId,
- NLog::PRI_INFO,
- NLog::PRI_DEBUG,
- 0U);
-
- loggerSettings->Append(
- NActorsServices::EServiceCommon_MIN,
- NActorsServices::EServiceCommon_MAX,
- NActorsServices::EServiceCommon_Name
- );
-
- constexpr ui32 WilsonComponentId = 430; // NKikimrServices::WILSON
- static const TString WilsonComponentName = "WILSON";
-
- loggerSettings->Append(
- (NLog::EComponent)WilsonComponentId,
- (NLog::EComponent)WilsonComponentId + 1,
- [](NLog::EComponent) -> const TString & { return WilsonComponentName; });
- }
-
- // register nameserver table
- auto names = MakeIntrusive<TTableNameserverSetup>();
- for (ui32 i = 1; i <= numNodes; ++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));
-
- // register logger
- setup.LocalServices.emplace_back(loggerActorId, TActorSetupCmd(new TLoggerActor(loggerSettings,
- CreateStderrBackend(), counters->GetSubgroup("subsystem", "logger")),
- TMailboxType::ReadAsFilled, 1));
-
- if (common->OutgoingHandshakeInflightLimit) {
- // create handshake broker actor
- setup.LocalServices.emplace_back(MakeHandshakeBrokerOutId(), TActorSetupCmd(
- CreateHandshakeBroker(*common->OutgoingHandshakeInflightLimit),
- TMailboxType::ReadAsFilled, interconnectPoolId));
- }
-
- auto sp = MakeHolder<TActorSystemSetup>(std::move(setup));
- ActorSystem.Reset(new TActorSystem(sp, nullptr, loggerSettings));
- ActorSystem->Start();
- }
-
- ~TNode() {
- ActorSystem->Stop();
- }
-
- bool Send(const TActorId& recipient, IEventBase* ev) {
- return ActorSystem->Send(recipient, ev);
- }
-
- TActorId RegisterActor(IActor* actor) {
- return ActorSystem->Register(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();
- }
-};
diff --git a/library/cpp/actors/interconnect/ut/lib/test_actors.h b/library/cpp/actors/interconnect/ut/lib/test_actors.h
deleted file mode 100644
index 7591200471..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/test_actors.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#pragma once
-
-namespace NActors {
- class TSenderBaseActor: public TActorBootstrapped<TSenderBaseActor> {
- protected:
- const TActorId RecipientActorId;
- const ui32 Preload;
- ui64 SequenceNumber = 0;
- ui32 InFlySize = 0;
-
- public:
- TSenderBaseActor(const TActorId& recipientActorId, ui32 preload = 1)
- : RecipientActorId(recipientActorId)
- , Preload(preload)
- {
- }
-
- virtual ~TSenderBaseActor() {
- }
-
- virtual void Bootstrap(const TActorContext& ctx) {
- Become(&TSenderBaseActor::StateFunc);
- ctx.Send(ctx.ExecutorThread.ActorSystem->InterconnectProxy(RecipientActorId.NodeId()), new TEvInterconnect::TEvConnectNode);
- }
-
- virtual void SendMessagesIfPossible(const TActorContext& ctx) {
- while (InFlySize < Preload) {
- SendMessage(ctx);
- }
- }
-
- virtual void SendMessage(const TActorContext& /*ctx*/) {
- ++SequenceNumber;
- }
-
- virtual void Handle(TEvents::TEvUndelivered::TPtr& /*ev*/, const TActorContext& ctx) {
- SendMessage(ctx);
- }
-
- virtual void Handle(TEvTestResponse::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*/) {
- }
-
- virtual void Handle(TEvents::TEvPoisonPill::TPtr& /*ev*/, const TActorContext& ctx) {
- 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)
- )
- };
-
- class TReceiverBaseActor: public TActor<TReceiverBaseActor> {
- protected:
- ui64 ReceivedCount = 0;
-
- public:
- TReceiverBaseActor()
- : TActor(&TReceiverBaseActor::StateFunc)
- {
- }
-
- virtual ~TReceiverBaseActor() {
- }
-
- virtual STRICT_STFUNC(StateFunc,
- HFunc(TEvTest, Handle)
- )
-
- virtual void Handle(TEvTest::TPtr& /*ev*/, const TActorContext& /*ctx*/) {}
- };
-}
diff --git a/library/cpp/actors/interconnect/ut/lib/test_events.h b/library/cpp/actors/interconnect/ut/lib/test_events.h
deleted file mode 100644
index 1bb5eb7d38..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/test_events.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/interconnect/ut/protos/interconnect_test.pb.h>
-
-namespace NActors {
- enum {
- EvTest = EventSpaceBegin(TEvents::ES_PRIVATE),
- EvTestChan,
- EvTestSmall,
- EvTestLarge,
- EvTestResponse,
- EvTestStartPolling,
- };
-
- struct TEvTest : TEventPB<TEvTest, NInterconnectTest::TEvTest, EvTest> {
- TEvTest() = default;
-
- TEvTest(ui64 sequenceNumber, const TString& payload) {
- Record.SetSequenceNumber(sequenceNumber);
- Record.SetPayload(payload);
- }
- };
-
- struct TEvTestLarge : TEventPB<TEvTestLarge, NInterconnectTest::TEvTestLarge, EvTestLarge> {
- TEvTestLarge() = default;
-
- TEvTestLarge(ui64 sequenceNumber, const TString& payload) {
- Record.SetSequenceNumber(sequenceNumber);
- Record.SetPayload(payload);
- }
- };
-
- struct TEvTestSmall : TEventPB<TEvTestSmall, NInterconnectTest::TEvTestSmall, EvTestSmall> {
- TEvTestSmall() = default;
-
- TEvTestSmall(ui64 sequenceNumber, const TString& payload) {
- Record.SetSequenceNumber(sequenceNumber);
- Record.SetPayload(payload);
- }
- };
-
- struct TEvTestResponse : TEventPB<TEvTestResponse, NInterconnectTest::TEvTestResponse, EvTestResponse> {
- TEvTestResponse() = default;
-
- TEvTestResponse(ui64 confirmedSequenceNumber) {
- Record.SetConfirmedSequenceNumber(confirmedSequenceNumber);
- }
- };
-
- struct TEvTestStartPolling : TEventPB<TEvTestStartPolling, NInterconnectTest::TEvTestStartPolling, EvTestStartPolling> {
- TEvTestStartPolling() = default;
- };
-
-}
diff --git a/library/cpp/actors/interconnect/ut/lib/ya.make b/library/cpp/actors/interconnect/ut/lib/ya.make
deleted file mode 100644
index 615c6a0e54..0000000000
--- a/library/cpp/actors/interconnect/ut/lib/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-LIBRARY()
-
-SRCS(
- node.h
- test_events.h
- test_actors.h
- ic_test_cluster.h
-)
-
-END()
diff --git a/library/cpp/actors/interconnect/ut/outgoing_stream_ut.cpp b/library/cpp/actors/interconnect/ut/outgoing_stream_ut.cpp
deleted file mode 100644
index 4834e48765..0000000000
--- a/library/cpp/actors/interconnect/ut/outgoing_stream_ut.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-#include <library/cpp/actors/interconnect/outgoing_stream.h>
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/entropy.h>
-#include <util/stream/null.h>
-
-#define Ctest Cnull
-
-Y_UNIT_TEST_SUITE(OutgoingStream) {
- Y_UNIT_TEST(Basic) {
- std::vector<char> buffer;
- buffer.resize(4 << 20);
-
- TReallyFastRng32 rng(EntropyPool());
- for (char *p = buffer.data(); p != buffer.data() + buffer.size(); p += sizeof(ui32)) {
- *reinterpret_cast<ui32*>(p) = rng();
- }
-
- for (ui32 nIter = 0; nIter < 10; ++nIter) {
- Cerr << "nIter# " << nIter << Endl;
-
- size_t base = 0; // number of dropped bytes
- size_t sendOffset = 0; // offset to base
- size_t pending = 0; // number of bytes in queue
-
- NInterconnect::TOutgoingStreamT<4096> stream;
-
- size_t numRewindsRemain = 10;
-
- while (base != buffer.size()) {
- const size_t bytesToEnd = buffer.size() - (base + sendOffset);
-
- Ctest << "base# " << base << " sendOffset# " << sendOffset << " pending# " << pending
- << " bytesToEnd# " << bytesToEnd;
-
- UNIT_ASSERT_VALUES_EQUAL(stream.CalculateOutgoingSize(), pending + sendOffset);
- UNIT_ASSERT_VALUES_EQUAL(stream.CalculateUnsentSize(), pending);
-
- const size_t maxBuffers = 128;
- std::vector<NActors::TConstIoVec> iov;
- stream.ProduceIoVec(iov, maxBuffers, Max<size_t>());
- size_t offset = base + sendOffset;
- for (const auto& [ptr, len] : iov) {
- UNIT_ASSERT(memcmp(buffer.data() + offset, ptr, len) == 0);
- offset += len;
- }
- UNIT_ASSERT(iov.size() == maxBuffers || offset == base + sendOffset + pending);
-
- const char *nextData = buffer.data() + base + sendOffset + pending;
- const size_t nextDataMaxLen = bytesToEnd - pending;
- const size_t nextDataLen = nextDataMaxLen ? rng() % Min<size_t>(16384, nextDataMaxLen) + 1 : 0;
-
- if (size_t bytesToScan = sendOffset + pending) {
- bytesToScan = rng() % bytesToScan + 1;
- size_t offset = base + sendOffset + pending - bytesToScan;
- stream.ScanLastBytes(bytesToScan, [&](TContiguousSpan span) {
- UNIT_ASSERT(offset + span.size() <= base + sendOffset + pending);
- UNIT_ASSERT(memcmp(buffer.data() + offset, span.data(), span.size()) == 0);
- offset += span.size();
- });
- UNIT_ASSERT_VALUES_EQUAL(offset, base + sendOffset + pending);
- }
-
- enum class EAction {
- COPY_APPEND,
- WRITE,
- REF_APPEND,
- ADVANCE,
- REWIND,
- DROP,
- BOOKMARK
- };
-
- std::vector<EAction> actions;
- if (nextDataLen) {
- actions.push_back(EAction::COPY_APPEND);
- actions.push_back(EAction::WRITE);
- actions.push_back(EAction::REF_APPEND);
- actions.push_back(EAction::BOOKMARK);
- }
- if (numRewindsRemain && sendOffset > 65536) {
- actions.push_back(EAction::REWIND);
- }
- actions.push_back(EAction::ADVANCE);
- actions.push_back(EAction::DROP);
-
- switch (actions[rng() % actions.size()]) {
- case EAction::COPY_APPEND: {
- Ctest << " COPY_APPEND nextDataLen# " << nextDataLen;
- auto span = stream.AcquireSpanForWriting(nextDataLen);
- UNIT_ASSERT(span.size() != 0);
- memcpy(span.data(), nextData, span.size());
- stream.Append(span);
- pending += span.size();
- break;
- }
-
- case EAction::WRITE:
- Ctest << " WRITE nextDataLen# " << nextDataLen;
- stream.Write({nextData, nextDataLen});
- pending += nextDataLen;
- break;
-
- case EAction::REF_APPEND:
- Ctest << " REF_APPEND nextDataLen# " << nextDataLen;
- stream.Append({nextData, nextDataLen});
- pending += nextDataLen;
- break;
-
- case EAction::ADVANCE: {
- const size_t advance = rng() % Min<size_t>(4096, pending + 1);
- Ctest << " ADVANCE advance# " << advance;
- stream.Advance(advance);
- sendOffset += advance;
- pending -= advance;
- break;
- }
-
- case EAction::REWIND:
- Ctest << " REWIND";
- stream.Rewind();
- pending += sendOffset;
- sendOffset = 0;
- --numRewindsRemain;
- break;
-
- case EAction::DROP: {
- const size_t drop = rng() % Min<size_t>(65536, sendOffset + 1);
- Ctest << " DROP drop# " << drop;
- stream.DropFront(drop);
- base += drop;
- sendOffset -= drop;
- break;
- }
-
- case EAction::BOOKMARK:
- Ctest << " BOOKMARK nextDataLen# " << nextDataLen;
- auto bookmark = stream.Bookmark(nextDataLen);
- stream.WriteBookmark(std::move(bookmark), {nextData, nextDataLen});
- pending += nextDataLen;
- break;
- }
-
- Ctest << Endl;
- }
- }
- }
-}
diff --git a/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp b/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp
deleted file mode 100644
index 38b9b5a0b6..0000000000
--- a/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-#include <library/cpp/actors/interconnect/poller_actor.h>
-#include <library/cpp/actors/testlib/test_runtime.h>
-
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/network/pair.h>
-#include <util/network/socket.h>
-
-using namespace NActors;
-
-class TTestSocket: public TSharedDescriptor {
-public:
- explicit TTestSocket(SOCKET fd)
- : Fd_(fd)
- {
- }
-
- int GetDescriptor() override {
- return Fd_;
- }
-
-private:
- SOCKET Fd_;
-};
-using TTestSocketPtr = TIntrusivePtr<TTestSocket>;
-
-// create pair of connected, non-blocking sockets
-std::pair<TTestSocketPtr, TTestSocketPtr> NonBlockSockets() {
- SOCKET fds[2];
- SocketPair(fds);
- SetNonBlock(fds[0]);
- SetNonBlock(fds[1]);
- 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_ABORT_UNLESS(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_ABORT("bind() failed with %s", strerror(errno));
- } else if (listen(server, 1) == -1) {
- Y_ABORT("listen() failed with %s", strerror(errno));
- }
-
- // obtain local address for client
- socklen_t len = sizeof(addr);
- if (getsockname(server, (sockaddr*)&addr, &len) == -1) {
- Y_ABORT("getsockname() failed with %s", strerror(errno));
- }
-
- // create client socket
- SOCKET client = socket(AF_INET, SOCK_STREAM, 0);
- Y_ABORT_UNLESS(client != -1, "socket() failed with %s", strerror(errno));
-
- // connect to server
- if (connect(client, (sockaddr*)&addr, len) == -1) {
- Y_ABORT("connect() failed with %s", strerror(errno));
- }
-
- // accept connection from the other side
- SOCKET accepted = accept(server, nullptr, nullptr);
- Y_ABORT_UNLESS(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)
- UNIT_TEST(ReadNotification)
- UNIT_TEST(WriteNotification)
- UNIT_TEST(HangupNotification)
- UNIT_TEST_SUITE_END();
-
-public:
- void SetUp() override {
- ActorSystem_ = MakeHolder<TTestActorRuntimeBase>();
- ActorSystem_->Initialize();
-
- PollerId_ = ActorSystem_->Register(CreatePollerActor());
-
- TDispatchOptions opts;
- opts.FinalEvents.emplace_back(TEvents::TSystem::Bootstrap, 1);
- ActorSystem_->DispatchEvents(opts);
- }
-
- void Registration() {
- auto [s1, s2] = NonBlockSockets();
- auto readerId = ActorSystem_->AllocateEdgeActor();
- auto writerId = ActorSystem_->AllocateEdgeActor();
-
- RegisterSocket(s1, readerId, writerId);
-
- // reader should receive event after socket registration
- TPollerToken::TPtr token;
- {
- 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);
- }
- }
-
- void ReadNotification() {
- auto [r, w] = NonBlockSockets();
- auto clientId = ActorSystem_->AllocateEdgeActor();
- RegisterSocket(r, clientId, {});
-
- // notification after registration
- TPollerToken::TPtr token;
- {
- auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId);
- token = ev->Get()->PollerToken;
- }
-
- char buf;
-
- // data not ready yet for read
- UNIT_ASSERT(read(r->GetDescriptor(), &buf, sizeof(buf)) == -1);
- UNIT_ASSERT(errno == EWOULDBLOCK);
-
- // 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);
- }
-
- // read data
- UNIT_ASSERT(read(r->GetDescriptor(), &buf, sizeof(buf)) == 1);
- UNIT_ASSERT_EQUAL('x', buf);
-
- // no more data to read
- UNIT_ASSERT(read(r->GetDescriptor(), &buf, sizeof(buf)) == -1);
- UNIT_ASSERT(errno == EWOULDBLOCK);
- }
-
- void WriteNotification() {
- auto [r, w] = TcpSockets();
- auto clientId = ActorSystem_->AllocateEdgeActor();
- SetNonBlock(w->GetDescriptor());
- RegisterSocket(w, TActorId{}, clientId);
-
- // notification after registration
- 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()");
- } 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()");
- }
- }
- }
- 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{});
-
- // notification after registration
- TPollerToken::TPtr token;
- {
- auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId);
- token = ev->Get()->PollerToken;
- }
-
- token->Request(true, false);
- ShutDown(w->GetDescriptor(), SHUT_RDWR);
-
- // 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);
- }
- }
-
-private:
- void RegisterSocket(TTestSocketPtr socket, TActorId readActorId, TActorId writeActorId) {
- auto ev = new TEvPollerRegister{socket, readActorId, writeActorId};
- ActorSystem_->Send(new IEventHandle(PollerId_, TActorId{}, ev));
- }
-
-private:
- THolder<TTestActorRuntimeBase> ActorSystem_;
- TActorId PollerId_;
-};
-
-UNIT_TEST_SUITE_REGISTRATION(TPollerActorTest);
diff --git a/library/cpp/actors/interconnect/ut/protos/CMakeLists.darwin-arm64.txt b/library/cpp/actors/interconnect/ut/protos/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 01f1765c08..0000000000
--- a/library/cpp/actors/interconnect/ut/protos/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_library(interconnect-ut-protos)
-target_link_libraries(interconnect-ut-protos PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-protobuf
-)
-target_proto_messages(interconnect-ut-protos PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/protos/interconnect_test.proto
-)
-target_proto_addincls(interconnect-ut-protos
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(interconnect-ut-protos
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
diff --git a/library/cpp/actors/interconnect/ut/protos/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/interconnect/ut/protos/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 01f1765c08..0000000000
--- a/library/cpp/actors/interconnect/ut/protos/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_library(interconnect-ut-protos)
-target_link_libraries(interconnect-ut-protos PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-protobuf
-)
-target_proto_messages(interconnect-ut-protos PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/protos/interconnect_test.proto
-)
-target_proto_addincls(interconnect-ut-protos
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(interconnect-ut-protos
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
diff --git a/library/cpp/actors/interconnect/ut/protos/CMakeLists.linux-aarch64.txt b/library/cpp/actors/interconnect/ut/protos/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 10cf33244c..0000000000
--- a/library/cpp/actors/interconnect/ut/protos/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_library(interconnect-ut-protos)
-target_link_libraries(interconnect-ut-protos PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-protobuf
-)
-target_proto_messages(interconnect-ut-protos PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/protos/interconnect_test.proto
-)
-target_proto_addincls(interconnect-ut-protos
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(interconnect-ut-protos
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
diff --git a/library/cpp/actors/interconnect/ut/protos/CMakeLists.linux-x86_64.txt b/library/cpp/actors/interconnect/ut/protos/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 10cf33244c..0000000000
--- a/library/cpp/actors/interconnect/ut/protos/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_library(interconnect-ut-protos)
-target_link_libraries(interconnect-ut-protos PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-protobuf
-)
-target_proto_messages(interconnect-ut-protos PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/protos/interconnect_test.proto
-)
-target_proto_addincls(interconnect-ut-protos
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(interconnect-ut-protos
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
diff --git a/library/cpp/actors/interconnect/ut/protos/CMakeLists.txt b/library/cpp/actors/interconnect/ut/protos/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/interconnect/ut/protos/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/interconnect/ut/protos/CMakeLists.windows-x86_64.txt b/library/cpp/actors/interconnect/ut/protos/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 01f1765c08..0000000000
--- a/library/cpp/actors/interconnect/ut/protos/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_library(interconnect-ut-protos)
-target_link_libraries(interconnect-ut-protos PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-protobuf
-)
-target_proto_messages(interconnect-ut-protos PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut/protos/interconnect_test.proto
-)
-target_proto_addincls(interconnect-ut-protos
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(interconnect-ut-protos
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
diff --git a/library/cpp/actors/interconnect/ut/protos/interconnect_test.proto b/library/cpp/actors/interconnect/ut/protos/interconnect_test.proto
deleted file mode 100644
index b74d068a8b..0000000000
--- a/library/cpp/actors/interconnect/ut/protos/interconnect_test.proto
+++ /dev/null
@@ -1,28 +0,0 @@
-package NInterconnectTest;
-
-message TEvTest {
- optional uint64 SequenceNumber = 1;
- optional bytes Payload = 2;
-}
-
-message TEvTestChan {
- optional uint64 SequenceNumber = 1;
- optional uint64 Payload = 2;
-}
-
-message TEvTestLarge {
- optional uint64 SequenceNumber = 1;
- optional bytes Payload = 2;
-}
-
-message TEvTestSmall {
- optional uint64 SequenceNumber = 1;
- optional bytes Payload = 2;
-}
-
-message TEvTestResponse {
- optional uint64 ConfirmedSequenceNumber = 1;
-}
-
-message TEvTestStartPolling {
-}
diff --git a/library/cpp/actors/interconnect/ut/protos/ya.make b/library/cpp/actors/interconnect/ut/protos/ya.make
deleted file mode 100644
index a7ffcd6bd0..0000000000
--- a/library/cpp/actors/interconnect/ut/protos/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-PROTO_LIBRARY()
-
-SRCS(
- interconnect_test.proto
-)
-
-EXCLUDE_TAGS(GO_PROTO)
-
-END()
diff --git a/library/cpp/actors/interconnect/ut/sticking_ut.cpp b/library/cpp/actors/interconnect/ut/sticking_ut.cpp
deleted file mode 100644
index 2fa3d0933e..0000000000
--- a/library/cpp/actors/interconnect/ut/sticking_ut.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-#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>
-
-using namespace NActors;
-
-struct TEvPing : TEventBase<TEvPing, TEvents::THelloWorld::Ping> {
- TString Data;
-
- TEvPing(TString data)
- : Data(data)
- {}
-
- TEvPing() = default;
-
- ui32 CalculateSerializedSize() const override { return Data.size(); }
- bool IsSerializable() const override { return true; }
- bool SerializeToArcadiaStream(TChunkSerializer *serializer) const override { serializer->WriteAliasedRaw(Data.data(), Data.size()); return true; }
- TString ToStringHeader() const override { return {}; }
-};
-
-class TPonger : public TActor<TPonger> {
-public:
- TPonger()
- : TActor(&TThis::StateFunc)
- {}
-
- void Handle(TEvPing::TPtr ev) {
- Send(ev->Sender, new TEvents::TEvPong(), 0, ev->Cookie);
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvPing, Handle);
- )
-};
-
-class TPinger : public TActorBootstrapped<TPinger> {
- ui32 PingInFlight = 0;
- TActorId PongerId;
- TDuration MaxRTT;
-
-public:
- TPinger(TActorId pongerId)
- : PongerId(pongerId)
- {}
-
- void Bootstrap() {
- Become(&TThis::StateFunc);
- Action();
- }
-
- void Action() {
- if (PingInFlight) {
- return;
- }
- const ui32 max = 1 + RandomNumber(10u);
- while (PingInFlight < max) {
- IssuePing();
- }
- }
-
- void IssuePing() {
- TString data = TString::Uninitialized(RandomNumber<size_t>(256 * 1024) + 1);
- memset(data.Detach(), 0, data.size());
- Send(PongerId, new TEvPing(data), 0, GetCycleCountFast());
- ++PingInFlight;
- }
-
- void Handle(TEvents::TEvPong::TPtr ev) {
- const TDuration rtt = CyclesToDuration(GetCycleCountFast() - ev->Cookie);
- if (MaxRTT < rtt) {
- MaxRTT = rtt;
- Cerr << "Updated MaxRTT# " << MaxRTT << Endl;
- Y_ABORT_UNLESS(MaxRTT <= TDuration::MilliSeconds(500));
- }
- --PingInFlight;
- Action();
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvents::TEvPong, Handle);
- )
-};
-
-Y_UNIT_TEST_SUITE(Sticking) {
- Y_UNIT_TEST(Check) {
- TPortManager portman;
- THashMap<ui32, ui16> nodeToPort;
- nodeToPort.emplace(1, portman.GetPort());
- nodeToPort.emplace(2, portman.GetPort());
-
- NMonitoring::TDynamicCounterPtr counters = new NMonitoring::TDynamicCounters;
- std::list<TNode> nodes;
- for (auto [nodeId, _] : nodeToPort) {
- nodes.emplace_back(nodeId, nodeToPort.size(), nodeToPort, "127.1.0.0",
- counters->GetSubgroup("nodeId", TStringBuilder() << nodeId), TDuration::Seconds(10),
- TChannelsConfig(), 0, 1, nullptr, 40 << 20);
- }
-
- auto& node1 = *nodes.begin();
- auto& node2 = *++nodes.begin();
-
- const TActorId ponger = node2.RegisterActor(new TPonger());
- node1.RegisterActor(new TPinger(ponger));
-
- Sleep(TDuration::Seconds(10));
- }
-}
diff --git a/library/cpp/actors/interconnect/ut/ya.make b/library/cpp/actors/interconnect/ut/ya.make
deleted file mode 100644
index e5b838635f..0000000000
--- a/library/cpp/actors/interconnect/ut/ya.make
+++ /dev/null
@@ -1,33 +0,0 @@
-UNITTEST()
-
-IF (SANITIZER_TYPE == "thread")
- TIMEOUT(1200)
- SIZE(LARGE)
- TAG(ya:fat)
-ELSE()
- TIMEOUT(600)
- SIZE(MEDIUM)
-ENDIF()
-
-SRCS(
- channel_scheduler_ut.cpp
- event_holder_pool_ut.cpp
- interconnect_ut.cpp
- large.cpp
- outgoing_stream_ut.cpp
- poller_actor_ut.cpp
- dynamic_proxy_ut.cpp
- sticking_ut.cpp
-)
-
-PEERDIR(
- library/cpp/actors/core
- library/cpp/actors/interconnect
- library/cpp/actors/interconnect/ut/lib
- library/cpp/actors/interconnect/ut/protos
- library/cpp/actors/testlib
- library/cpp/digest/md5
- library/cpp/testing/unittest
-)
-
-END()
diff --git a/library/cpp/actors/interconnect/ut_fat/CMakeLists.darwin-arm64.txt b/library/cpp/actors/interconnect/ut_fat/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index ad106fc729..0000000000
--- a/library/cpp/actors/interconnect/ut_fat/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-interconnect-ut_fat)
-target_link_libraries(library-cpp-actors-interconnect-ut_fat PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- actors-interconnect-mock
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-testing-unittest
- cpp-deprecated-atomic
-)
-target_link_options(library-cpp-actors-interconnect-ut_fat PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-interconnect-ut_fat PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut_fat/main.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut_fat
- TEST_TARGET
- library-cpp-actors-interconnect-ut_fat
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- LABELS
- LARGE
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-interconnect-ut_fat
- system_allocator
-)
-vcs_info(library-cpp-actors-interconnect-ut_fat)
diff --git a/library/cpp/actors/interconnect/ut_fat/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/interconnect/ut_fat/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 4285513499..0000000000
--- a/library/cpp/actors/interconnect/ut_fat/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-interconnect-ut_fat)
-target_link_libraries(library-cpp-actors-interconnect-ut_fat PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- actors-interconnect-mock
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-testing-unittest
- cpp-deprecated-atomic
-)
-target_link_options(library-cpp-actors-interconnect-ut_fat PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-interconnect-ut_fat PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut_fat/main.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut_fat
- TEST_TARGET
- library-cpp-actors-interconnect-ut_fat
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- LABELS
- LARGE
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-interconnect-ut_fat
- system_allocator
-)
-vcs_info(library-cpp-actors-interconnect-ut_fat)
diff --git a/library/cpp/actors/interconnect/ut_fat/CMakeLists.linux-aarch64.txt b/library/cpp/actors/interconnect/ut_fat/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 5365ba4e24..0000000000
--- a/library/cpp/actors/interconnect/ut_fat/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-interconnect-ut_fat)
-target_link_libraries(library-cpp-actors-interconnect-ut_fat PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- actors-interconnect-mock
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-testing-unittest
- cpp-deprecated-atomic
-)
-target_link_options(library-cpp-actors-interconnect-ut_fat PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-interconnect-ut_fat PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut_fat/main.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut_fat
- TEST_TARGET
- library-cpp-actors-interconnect-ut_fat
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- LABELS
- LARGE
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-interconnect-ut_fat
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-interconnect-ut_fat)
diff --git a/library/cpp/actors/interconnect/ut_fat/CMakeLists.linux-x86_64.txt b/library/cpp/actors/interconnect/ut_fat/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 86ef393bab..0000000000
--- a/library/cpp/actors/interconnect/ut_fat/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-interconnect-ut_fat)
-target_link_libraries(library-cpp-actors-interconnect-ut_fat PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- actors-interconnect-mock
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-testing-unittest
- cpp-deprecated-atomic
-)
-target_link_options(library-cpp-actors-interconnect-ut_fat PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-interconnect-ut_fat PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut_fat/main.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut_fat
- TEST_TARGET
- library-cpp-actors-interconnect-ut_fat
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- LABELS
- LARGE
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-interconnect-ut_fat
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-interconnect-ut_fat)
diff --git a/library/cpp/actors/interconnect/ut_fat/CMakeLists.txt b/library/cpp/actors/interconnect/ut_fat/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/interconnect/ut_fat/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/interconnect/ut_fat/CMakeLists.windows-x86_64.txt b/library/cpp/actors/interconnect/ut_fat/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 3841949a28..0000000000
--- a/library/cpp/actors/interconnect/ut_fat/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-interconnect-ut_fat)
-target_link_libraries(library-cpp-actors-interconnect-ut_fat PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- actors-interconnect-mock
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-testing-unittest
- cpp-deprecated-atomic
-)
-target_sources(library-cpp-actors-interconnect-ut_fat PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut_fat/main.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut_fat
- TEST_TARGET
- library-cpp-actors-interconnect-ut_fat
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- LABELS
- LARGE
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_fat
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-interconnect-ut_fat
- system_allocator
-)
-vcs_info(library-cpp-actors-interconnect-ut_fat)
diff --git a/library/cpp/actors/interconnect/ut_fat/main.cpp b/library/cpp/actors/interconnect/ut_fat/main.cpp
deleted file mode 100644
index abd1cd289a..0000000000
--- a/library/cpp/actors/interconnect/ut_fat/main.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-
-#include <library/cpp/actors/interconnect/interconnect_tcp_proxy.h>
-#include <library/cpp/actors/interconnect/ut/protos/interconnect_test.pb.h>
-#include <library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h>
-#include <library/cpp/actors/interconnect/ut/lib/interrupter.h>
-#include <library/cpp/actors/interconnect/ut/lib/test_events.h>
-#include <library/cpp/actors/interconnect/ut/lib/test_actors.h>
-#include <library/cpp/actors/interconnect/ut/lib/node.h>
-
-#include <library/cpp/testing/unittest/tests_data.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/network/sock.h>
-#include <util/network/poller.h>
-#include <library/cpp/deprecated/atomic/atomic.h>
-#include <util/generic/set.h>
-
-Y_UNIT_TEST_SUITE(InterconnectUnstableConnection) {
- using namespace NActors;
-
- class TSenderActor: public TSenderBaseActor {
- TDeque<ui64> InFly;
- ui16 SendFlags;
-
- public:
- TSenderActor(const TActorId& recipientActorId, ui16 sendFlags)
- : TSenderBaseActor(recipientActorId, 32)
- , SendFlags(sendFlags)
- {
- }
-
- ~TSenderActor() override {
- Cerr << "Sent " << SequenceNumber << " messages\n";
- }
-
- void SendMessage(const TActorContext& ctx) override {
- const ui32 flags = IEventHandle::MakeFlags(0, SendFlags);
- const ui64 cookie = SequenceNumber;
- const TString payload('@', RandomNumber<size_t>(65536) + 4096);
- ctx.Send(RecipientActorId, new TEvTest(SequenceNumber, payload), flags, cookie);
- InFly.push_back(SequenceNumber);
- ++InFlySize;
- ++SequenceNumber;
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr& ev, const TActorContext& ctx) override {
- auto record = std::find(InFly.begin(), InFly.end(), ev->Cookie);
- if (SendFlags & IEventHandle::FlagGenerateUnsureUndelivered) {
- if (record != InFly.end()) {
- InFly.erase(record);
- --InFlySize;
- SendMessage(ctx);
- }
- } else {
- Y_ABORT_UNLESS(record != InFly.end());
- }
- }
-
- void Handle(TEvTestResponse::TPtr& ev, const TActorContext& ctx) override {
- Y_ABORT_UNLESS(InFly);
- const NInterconnectTest::TEvTestResponse& record = ev->Get()->Record;
- Y_ABORT_UNLESS(record.HasConfirmedSequenceNumber());
- if (!(SendFlags & IEventHandle::FlagGenerateUnsureUndelivered)) {
- while (record.GetConfirmedSequenceNumber() != InFly.front()) {
- InFly.pop_front();
- --InFlySize;
- }
- }
- Y_ABORT_UNLESS(record.GetConfirmedSequenceNumber() == InFly.front(), "got# %" PRIu64 " expected# %" PRIu64,
- record.GetConfirmedSequenceNumber(), InFly.front());
- InFly.pop_front();
- --InFlySize;
- SendMessagesIfPossible(ctx);
- }
- };
-
- class TReceiverActor: public TReceiverBaseActor {
- ui64 ReceivedCount = 0;
- TNode* SenderNode = nullptr;
-
- public:
- TReceiverActor(TNode* senderNode)
- : TReceiverBaseActor()
- , SenderNode(senderNode)
- {
- }
-
- void Handle(TEvTest::TPtr& ev, const TActorContext& /*ctx*/) override {
- const NInterconnectTest::TEvTest& m = ev->Get()->Record;
- Y_ABORT_UNLESS(m.HasSequenceNumber());
- Y_ABORT_UNLESS(m.GetSequenceNumber() >= ReceivedCount, "got #%" PRIu64 " expected at least #%" PRIu64,
- m.GetSequenceNumber(), ReceivedCount);
- ++ReceivedCount;
- SenderNode->Send(ev->Sender, new TEvTestResponse(m.GetSequenceNumber()));
- }
-
- ~TReceiverActor() override {
- Cerr << "Received " << ReceivedCount << " messages\n";
- }
- };
-
- Y_UNIT_TEST(InterconnectTestWithProxyUnsureUndelivered) {
- ui32 numNodes = 2;
- double bandWidth = 1000000;
- ui16 flags = IEventHandle::FlagTrackDelivery | IEventHandle::FlagGenerateUnsureUndelivered;
- TTestICCluster::TTrafficInterrupterSettings interrupterSettings{TDuration::Seconds(2), bandWidth, true};
-
- TTestICCluster testCluster(numNodes, TChannelsConfig(), &interrupterSettings);
-
- TReceiverActor* receiverActor = new TReceiverActor(testCluster.GetNode(1));
- const TActorId recipient = testCluster.RegisterActor(receiverActor, 2);
- TSenderActor* senderActor = new TSenderActor(recipient, flags);
- testCluster.RegisterActor(senderActor, 1);
-
- NanoSleep(30ULL * 1000 * 1000 * 1000);
- }
-
- Y_UNIT_TEST(InterconnectTestWithProxy) {
- ui32 numNodes = 2;
- double bandWidth = 1000000;
- ui16 flags = IEventHandle::FlagTrackDelivery;
- TTestICCluster::TTrafficInterrupterSettings interrupterSettings{TDuration::Seconds(2), bandWidth, true};
-
- TTestICCluster testCluster(numNodes, TChannelsConfig(), &interrupterSettings);
-
- TReceiverActor* receiverActor = new TReceiverActor(testCluster.GetNode(1));
- const TActorId recipient = testCluster.RegisterActor(receiverActor, 2);
- TSenderActor* senderActor = new TSenderActor(recipient, flags);
- testCluster.RegisterActor(senderActor, 1);
-
- NanoSleep(30ULL * 1000 * 1000 * 1000);
- }
-}
diff --git a/library/cpp/actors/interconnect/ut_fat/ya.make b/library/cpp/actors/interconnect/ut_fat/ya.make
deleted file mode 100644
index 8361c5d9f7..0000000000
--- a/library/cpp/actors/interconnect/ut_fat/ya.make
+++ /dev/null
@@ -1,21 +0,0 @@
-UNITTEST()
-
-SIZE(LARGE)
-
-TAG(ya:fat)
-
-SRCS(
- main.cpp
-)
-
-PEERDIR(
- library/cpp/actors/core
- library/cpp/actors/interconnect
- library/cpp/actors/interconnect/mock
- library/cpp/actors/interconnect/ut/lib
- library/cpp/actors/interconnect/ut/protos
- library/cpp/testing/unittest
- library/cpp/deprecated/atomic
-)
-
-END()
diff --git a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.darwin-arm64.txt b/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index b91e1530bb..0000000000
--- a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-interconnect-ut_huge_cluster)
-target_link_libraries(library-cpp-actors-interconnect-ut_huge_cluster PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-testing-unittest
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-interconnect-ut_huge_cluster PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-interconnect-ut_huge_cluster PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut_huge_cluster/huge_cluster.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut_huge_cluster
- TEST_TARGET
- library-cpp-actors-interconnect-ut_huge_cluster
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- PROCESSORS
- 4
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-interconnect-ut_huge_cluster
- system_allocator
-)
-vcs_info(library-cpp-actors-interconnect-ut_huge_cluster)
diff --git a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 45fd7e2060..0000000000
--- a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-interconnect-ut_huge_cluster)
-target_link_libraries(library-cpp-actors-interconnect-ut_huge_cluster PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-testing-unittest
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-interconnect-ut_huge_cluster PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-interconnect-ut_huge_cluster PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut_huge_cluster/huge_cluster.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut_huge_cluster
- TEST_TARGET
- library-cpp-actors-interconnect-ut_huge_cluster
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- PROCESSORS
- 4
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-interconnect-ut_huge_cluster
- system_allocator
-)
-vcs_info(library-cpp-actors-interconnect-ut_huge_cluster)
diff --git a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.linux-aarch64.txt b/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 51c8af6a26..0000000000
--- a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-interconnect-ut_huge_cluster)
-target_link_libraries(library-cpp-actors-interconnect-ut_huge_cluster PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-testing-unittest
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-interconnect-ut_huge_cluster PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-interconnect-ut_huge_cluster PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut_huge_cluster/huge_cluster.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut_huge_cluster
- TEST_TARGET
- library-cpp-actors-interconnect-ut_huge_cluster
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- PROCESSORS
- 4
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-interconnect-ut_huge_cluster
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-interconnect-ut_huge_cluster)
diff --git a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.linux-x86_64.txt b/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 97a04cc102..0000000000
--- a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-interconnect-ut_huge_cluster)
-target_link_libraries(library-cpp-actors-interconnect-ut_huge_cluster PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-testing-unittest
- cpp-actors-testlib
-)
-target_link_options(library-cpp-actors-interconnect-ut_huge_cluster PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-interconnect-ut_huge_cluster PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut_huge_cluster/huge_cluster.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut_huge_cluster
- TEST_TARGET
- library-cpp-actors-interconnect-ut_huge_cluster
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- PROCESSORS
- 4
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-interconnect-ut_huge_cluster
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-interconnect-ut_huge_cluster)
diff --git a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.txt b/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.windows-x86_64.txt b/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 7155e17cd5..0000000000
--- a/library/cpp/actors/interconnect/ut_huge_cluster/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-interconnect-ut_huge_cluster)
-target_link_libraries(library-cpp-actors-interconnect-ut_huge_cluster PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-core
- cpp-actors-interconnect
- interconnect-ut-lib
- interconnect-ut-protos
- cpp-testing-unittest
- cpp-actors-testlib
-)
-target_sources(library-cpp-actors-interconnect-ut_huge_cluster PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/interconnect/ut_huge_cluster/huge_cluster.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-interconnect-ut_huge_cluster
- TEST_TARGET
- library-cpp-actors-interconnect-ut_huge_cluster
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- LABELS
- MEDIUM
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- PROCESSORS
- 4
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-interconnect-ut_huge_cluster
- PROPERTY
- TIMEOUT
- 600
-)
-target_allocator(library-cpp-actors-interconnect-ut_huge_cluster
- system_allocator
-)
-vcs_info(library-cpp-actors-interconnect-ut_huge_cluster)
diff --git a/library/cpp/actors/interconnect/ut_huge_cluster/huge_cluster.cpp b/library/cpp/actors/interconnect/ut_huge_cluster/huge_cluster.cpp
deleted file mode 100644
index cb46a62ed9..0000000000
--- a/library/cpp/actors/interconnect/ut_huge_cluster/huge_cluster.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-#include <library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h>
-#include <library/cpp/actors/interconnect/ut/lib/test_events.h>
-#include <library/cpp/actors/interconnect/ut/lib/test_actors.h>
-
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <vector>
-
-Y_UNIT_TEST_SUITE(HugeCluster) {
- using namespace NActors;
-
- class TPoller: public TActor<TPoller> {
- const std::vector<TActorId>& Targets;
- std::unordered_map<TActorId, TManualEvent>& Connected;
-
- public:
- TPoller(const std::vector<TActorId>& targets, std::unordered_map<TActorId, TManualEvent>& events)
- : TActor(&TPoller::StateFunc)
- , Targets(targets)
- , Connected(events)
- {}
-
- void Handle(TEvTestStartPolling::TPtr /*ev*/, const TActorContext& ctx) {
- for (ui32 i = 0; i < Targets.size(); ++i) {
- ctx.Send(Targets[i], new TEvTest(), IEventHandle::FlagTrackDelivery, i);
- }
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr ev, const TActorContext& ctx) {
- const ui32 cookie = ev->Cookie;
- // Cerr << "TEvUndelivered ping from node# " << SelfId().NodeId() << " to node# " << cookie + 1 << Endl;
- ctx.Send(Targets[cookie], new TEvTest(), IEventHandle::FlagTrackDelivery, cookie);
- }
-
- void Handle(TEvTest::TPtr ev, const TActorContext& /*ctx*/) {
- // Cerr << "Polled from " << ev->Sender.ToString() << Endl;
- Connected[ev->Sender].Signal();
- }
-
- void Handle(TEvents::TEvPoisonPill::TPtr& /*ev*/, const TActorContext& ctx) {
- Die(ctx);
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvents::TEvUndelivered, Handle)
- HFunc(TEvTestStartPolling, Handle)
- HFunc(TEvTest, Handle)
- HFunc(TEvents::TEvPoisonPill, Handle)
- )
- };
-
- class TStartPollers : public TActorBootstrapped<TStartPollers> {
- const std::vector<TActorId>& Pollers;
-
- public:
- TStartPollers(const std::vector<TActorId>& pollers)
- : Pollers(pollers)
- {}
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TThis::StateFunc);
- for (ui32 i = 0; i < Pollers.size(); ++i) {
- ctx.Send(Pollers[i], new TEvTestStartPolling(), IEventHandle::FlagTrackDelivery, i);
- }
- }
-
- void Handle(TEvents::TEvUndelivered::TPtr ev, const TActorContext& ctx) {
- const ui32 cookie = ev->Cookie;
- // Cerr << "TEvUndelivered start poller message to node# " << cookie + 1 << Endl;
- ctx.Send(Pollers[cookie], new TEvTestStartPolling(), IEventHandle::FlagTrackDelivery, cookie);
- }
-
- void Handle(TEvents::TEvPoisonPill::TPtr& /*ev*/, const TActorContext& ctx) {
- Die(ctx);
- }
-
- STRICT_STFUNC(StateFunc,
- HFunc(TEvents::TEvUndelivered, Handle)
- HFunc(TEvents::TEvPoisonPill, Handle)
- )
- };
-
- TIntrusivePtr<NLog::TSettings> MakeLogConfigs(NLog::EPriority priority) {
- // custom logger settings
- auto loggerSettings = MakeIntrusive<NLog::TSettings>(
- TActorId(0, "logger"),
- NActorsServices::LOGGER,
- priority,
- priority,
- 0U);
-
- loggerSettings->Append(
- NActorsServices::EServiceCommon_MIN,
- NActorsServices::EServiceCommon_MAX,
- NActorsServices::EServiceCommon_Name
- );
-
- constexpr ui32 WilsonComponentId = 430; // NKikimrServices::WILSON
- static const TString WilsonComponentName = "WILSON";
-
- loggerSettings->Append(
- (NLog::EComponent)WilsonComponentId,
- (NLog::EComponent)WilsonComponentId + 1,
- [](NLog::EComponent) -> const TString & { return WilsonComponentName; });
-
- return loggerSettings;
- }
-
- Y_UNIT_TEST(AllToAll) {
- ui32 nodesNum = 120;
- std::vector<TActorId> pollers(nodesNum);
- std::vector<std::unordered_map<TActorId, TManualEvent>> events(nodesNum);
-
- // Must destroy actor system before shared arrays
- {
- TTestICCluster testCluster(nodesNum, NActors::TChannelsConfig(), nullptr, MakeLogConfigs(NLog::PRI_EMERG));
-
- for (ui32 i = 0; i < nodesNum; ++i) {
- pollers[i] = testCluster.RegisterActor(new TPoller(pollers, events[i]), i + 1);
- }
-
- for (ui32 i = 0; i < nodesNum; ++i) {
- for (const auto& actor : pollers) {
- events[i][actor] = TManualEvent();
- }
- }
-
- testCluster.RegisterActor(new TStartPollers(pollers), 1);
-
- for (ui32 i = 0; i < nodesNum; ++i) {
- for (auto& [_, ev] : events[i]) {
- ev.WaitI();
- }
- }
- }
- }
-
-
- Y_UNIT_TEST(AllToOne) {
- ui32 nodesNum = 500;
- std::vector<TActorId> listeners;
- std::vector<TActorId> pollers(nodesNum - 1);
- std::unordered_map<TActorId, TManualEvent> events;
- std::unordered_map<TActorId, TManualEvent> emptyEventList;
-
- // Must destroy actor system before shared arrays
- {
- TTestICCluster testCluster(nodesNum, NActors::TChannelsConfig(), nullptr, MakeLogConfigs(NLog::PRI_EMERG));
-
- const TActorId listener = testCluster.RegisterActor(new TPoller({}, events), nodesNum);
- listeners = { listener };
- for (ui32 i = 0; i < nodesNum - 1; ++i) {
- pollers[i] = testCluster.RegisterActor(new TPoller(listeners, emptyEventList), i + 1);
- }
-
- for (const auto& actor : pollers) {
- events[actor] = TManualEvent();
- }
-
- testCluster.RegisterActor(new TStartPollers(pollers), 1);
-
- for (auto& [_, ev] : events) {
- ev.WaitI();
- }
- }
- }
-}
diff --git a/library/cpp/actors/interconnect/ut_huge_cluster/ya.make b/library/cpp/actors/interconnect/ut_huge_cluster/ya.make
deleted file mode 100644
index 828783323d..0000000000
--- a/library/cpp/actors/interconnect/ut_huge_cluster/ya.make
+++ /dev/null
@@ -1,34 +0,0 @@
-UNITTEST()
-
-IF (SANITIZER_TYPE OR WITH_VALGRIND)
- TIMEOUT(3600)
- SIZE(LARGE)
- TAG(ya:fat)
-ELSE()
- TIMEOUT(600)
- SIZE(MEDIUM)
-ENDIF()
-
-IF (BUILD_TYPE == "RELEASE" OR BUILD_TYPE == "RELWITHDEBINFO")
- SRCS(
- huge_cluster.cpp
- )
-ELSE ()
- MESSAGE(WARNING "It takes too much time to run test in DEBUG mode, some tests are skipped")
-ENDIF ()
-
-PEERDIR(
- library/cpp/actors/core
- library/cpp/actors/interconnect
- library/cpp/actors/interconnect/ut/lib
- library/cpp/actors/interconnect/ut/protos
- library/cpp/testing/unittest
- library/cpp/actors/testlib
-)
-
-REQUIREMENTS(
- cpu:4
- ram:32
-)
-
-END()
diff --git a/library/cpp/actors/interconnect/watchdog_timer.h b/library/cpp/actors/interconnect/watchdog_timer.h
deleted file mode 100644
index 2a5860f84c..0000000000
--- a/library/cpp/actors/interconnect/watchdog_timer.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#pragma once
-
-namespace NActors {
- template<typename TEvent>
- class TWatchdogTimer {
- using TCallback = std::function<void()>;
-
- const TDuration Timeout;
- const TCallback Callback;
-
- TMonotonic TriggerTimestamp = TMonotonic::Max();
- bool EventScheduled = false;
- ui32 Iteration;
-
- static constexpr ui32 NumIterationsBeforeFiring = 2;
-
- public:
- TWatchdogTimer(TDuration timeout, TCallback callback)
- : Timeout(timeout)
- , Callback(std::move(callback))
- {}
-
- void Rearm(const TActorIdentity& actor) {
- if (Timeout != TDuration::Zero() && Timeout != TDuration::Max()) {
- TriggerTimestamp = TActivationContext::Monotonic() + Timeout;
- Iteration = 0;
- Schedule(actor);
- }
- }
-
- void Disarm() {
- TriggerTimestamp = TMonotonic::Max();
- }
-
- bool Armed() const {
- return TriggerTimestamp != TMonotonic::Max();
- }
-
- void operator()(typename TEvent::TPtr& ev) {
- Y_DEBUG_ABORT_UNLESS(EventScheduled);
- EventScheduled = false;
- if (!Armed()) {
- // just do nothing
- } else if (TActivationContext::Monotonic() < TriggerTimestamp) {
- // the time hasn't come yet
- Schedule(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
- EventScheduled = true;
- } else {
- // no chance to disarm, fire callback
- Disarm();
- Callback();
- }
- }
-
- private:
- void Schedule(const TActorIdentity& actor) {
- Y_DEBUG_ABORT_UNLESS(Armed());
- if (!EventScheduled) {
- actor.Schedule(TriggerTimestamp, new TEvent);
- EventScheduled = true;
- }
- }
- };
-
-}
diff --git a/library/cpp/actors/interconnect/ya.make b/library/cpp/actors/interconnect/ya.make
deleted file mode 100644
index 9cb5bc7d8c..0000000000
--- a/library/cpp/actors/interconnect/ya.make
+++ /dev/null
@@ -1,97 +0,0 @@
-LIBRARY()
-
-NO_WSHADOW()
-
-IF (PROFILE_MEMORY_ALLOCATIONS)
- CFLAGS(-DPROFILE_MEMORY_ALLOCATIONS)
-ENDIF()
-
-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_counters.cpp
- 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_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
- 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(
- contrib/libs/libc_compat
- contrib/libs/openssl
- contrib/libs/xxhash
- library/cpp/actors/core
- library/cpp/actors/dnscachelib
- library/cpp/actors/dnsresolver
- library/cpp/actors/helpers
- library/cpp/actors/prof
- library/cpp/actors/protos
- library/cpp/actors/util
- library/cpp/actors/wilson
- library/cpp/digest/crc32c
- library/cpp/json
- library/cpp/lwtrace
- library/cpp/monlib/dynamic_counters
- library/cpp/monlib/metrics
- library/cpp/monlib/service/pages/resources
- library/cpp/monlib/service/pages/tablesorter
- library/cpp/openssl/init
- library/cpp/packedtypes
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- ut
- ut_fat
- ut_huge_cluster
-)
diff --git a/library/cpp/actors/log_backend/CMakeLists.darwin-arm64.txt b/library/cpp/actors/log_backend/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 2845e78e35..0000000000
--- a/library/cpp/actors/log_backend/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-log_backend)
-target_link_libraries(cpp-actors-log_backend PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- library-cpp-logger
-)
-target_sources(cpp-actors-log_backend PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/log_backend/actor_log_backend.cpp
-)
diff --git a/library/cpp/actors/log_backend/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/log_backend/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 2845e78e35..0000000000
--- a/library/cpp/actors/log_backend/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-log_backend)
-target_link_libraries(cpp-actors-log_backend PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- library-cpp-logger
-)
-target_sources(cpp-actors-log_backend PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/log_backend/actor_log_backend.cpp
-)
diff --git a/library/cpp/actors/log_backend/CMakeLists.linux-aarch64.txt b/library/cpp/actors/log_backend/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 15786d6c74..0000000000
--- a/library/cpp/actors/log_backend/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-log_backend)
-target_link_libraries(cpp-actors-log_backend PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- library-cpp-logger
-)
-target_sources(cpp-actors-log_backend PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/log_backend/actor_log_backend.cpp
-)
diff --git a/library/cpp/actors/log_backend/CMakeLists.linux-x86_64.txt b/library/cpp/actors/log_backend/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 15786d6c74..0000000000
--- a/library/cpp/actors/log_backend/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-log_backend)
-target_link_libraries(cpp-actors-log_backend PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- library-cpp-logger
-)
-target_sources(cpp-actors-log_backend PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/log_backend/actor_log_backend.cpp
-)
diff --git a/library/cpp/actors/log_backend/CMakeLists.txt b/library/cpp/actors/log_backend/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/log_backend/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/log_backend/CMakeLists.windows-x86_64.txt b/library/cpp/actors/log_backend/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 2845e78e35..0000000000
--- a/library/cpp/actors/log_backend/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-log_backend)
-target_link_libraries(cpp-actors-log_backend PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- library-cpp-logger
-)
-target_sources(cpp-actors-log_backend PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/log_backend/actor_log_backend.cpp
-)
diff --git a/library/cpp/actors/log_backend/actor_log_backend.cpp b/library/cpp/actors/log_backend/actor_log_backend.cpp
deleted file mode 100644
index a6fdd20c7b..0000000000
--- a/library/cpp/actors/log_backend/actor_log_backend.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "actor_log_backend.h"
-
-#include <library/cpp/actors/core/actorsystem.h>
-#include <library/cpp/actors/core/log.h>
-#include <library/cpp/logger/record.h>
-
-namespace {
-
-NActors::NLog::EPriority GetActorLogPriority(ELogPriority priority) {
- switch (priority) {
- case TLOG_EMERG:
- return NActors::NLog::PRI_EMERG;
- case TLOG_ALERT:
- return NActors::NLog::PRI_ALERT;
- case TLOG_CRIT:
- return NActors::NLog::PRI_CRIT;
- case TLOG_ERR:
- return NActors::NLog::PRI_ERROR;
- case TLOG_WARNING:
- return NActors::NLog::PRI_WARN;
- case TLOG_NOTICE:
- return NActors::NLog::PRI_NOTICE;
- case TLOG_INFO:
- return NActors::NLog::PRI_INFO;
- case TLOG_DEBUG:
- return NActors::NLog::PRI_DEBUG;
- default:
- return NActors::NLog::PRI_TRACE;
- }
-}
-
-}
-
-TActorLogBackend::TActorLogBackend(NActors::TActorSystem* actorSystem, int logComponent)
- : ActorSystem(actorSystem)
- , LogComponent(logComponent)
-{
-}
-
-void TActorLogBackend::WriteData(const TLogRecord& rec) {
- LOG_LOG(*ActorSystem, GetActorLogPriority(rec.Priority), LogComponent, TString(rec.Data, rec.Len));
-}
diff --git a/library/cpp/actors/log_backend/actor_log_backend.h b/library/cpp/actors/log_backend/actor_log_backend.h
deleted file mode 100644
index a51427d498..0000000000
--- a/library/cpp/actors/log_backend/actor_log_backend.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-#include <library/cpp/logger/backend.h>
-
-namespace NActors {
-class TActorSystem;
-} // namespace NActors
-
-class TActorLogBackend : public TLogBackend {
-public:
- TActorLogBackend(NActors::TActorSystem* actorSystem, int logComponent);
-
- void WriteData(const TLogRecord& rec) override;
-
- void ReopenLog() override {
- }
-
-private:
- NActors::TActorSystem* const ActorSystem;
- const int LogComponent;
-};
diff --git a/library/cpp/actors/log_backend/ya.make b/library/cpp/actors/log_backend/ya.make
deleted file mode 100644
index ce9f049e9a..0000000000
--- a/library/cpp/actors/log_backend/ya.make
+++ /dev/null
@@ -1,12 +0,0 @@
-LIBRARY()
-
-PEERDIR(
- library/cpp/actors/core
- library/cpp/logger
-)
-
-SRCS(
- actor_log_backend.cpp
-)
-
-END()
diff --git a/library/cpp/actors/memory_log/CMakeLists.darwin-arm64.txt b/library/cpp/actors/memory_log/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 5109f0fcce..0000000000
--- a/library/cpp/actors/memory_log/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-memory_log)
-target_link_libraries(cpp-actors-memory_log PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-threading-queue
- contrib-libs-linuxvdso
- cpp-deprecated-atomic
-)
-target_sources(cpp-actors-memory_log PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/memory_log/memlog.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/memory_log/mmap.cpp
-)
diff --git a/library/cpp/actors/memory_log/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/memory_log/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 5109f0fcce..0000000000
--- a/library/cpp/actors/memory_log/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-memory_log)
-target_link_libraries(cpp-actors-memory_log PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-threading-queue
- contrib-libs-linuxvdso
- cpp-deprecated-atomic
-)
-target_sources(cpp-actors-memory_log PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/memory_log/memlog.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/memory_log/mmap.cpp
-)
diff --git a/library/cpp/actors/memory_log/CMakeLists.linux-aarch64.txt b/library/cpp/actors/memory_log/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 1fa79db3ff..0000000000
--- a/library/cpp/actors/memory_log/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-memory_log)
-target_link_libraries(cpp-actors-memory_log PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-threading-queue
- contrib-libs-linuxvdso
- cpp-deprecated-atomic
-)
-target_sources(cpp-actors-memory_log PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/memory_log/memlog.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/memory_log/mmap.cpp
-)
diff --git a/library/cpp/actors/memory_log/CMakeLists.linux-x86_64.txt b/library/cpp/actors/memory_log/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 1fa79db3ff..0000000000
--- a/library/cpp/actors/memory_log/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-memory_log)
-target_link_libraries(cpp-actors-memory_log PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-threading-queue
- contrib-libs-linuxvdso
- cpp-deprecated-atomic
-)
-target_sources(cpp-actors-memory_log PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/memory_log/memlog.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/memory_log/mmap.cpp
-)
diff --git a/library/cpp/actors/memory_log/CMakeLists.txt b/library/cpp/actors/memory_log/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/memory_log/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/memory_log/CMakeLists.windows-x86_64.txt b/library/cpp/actors/memory_log/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 5109f0fcce..0000000000
--- a/library/cpp/actors/memory_log/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(cpp-actors-memory_log)
-target_link_libraries(cpp-actors-memory_log PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-threading-queue
- contrib-libs-linuxvdso
- cpp-deprecated-atomic
-)
-target_sources(cpp-actors-memory_log PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/memory_log/memlog.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/memory_log/mmap.cpp
-)
diff --git a/library/cpp/actors/memory_log/memlog.cpp b/library/cpp/actors/memory_log/memlog.cpp
deleted file mode 100644
index 263c5c5079..0000000000
--- a/library/cpp/actors/memory_log/memlog.cpp
+++ /dev/null
@@ -1,367 +0,0 @@
-#include "memlog.h"
-
-#include <library/cpp/actors/util/datetime.h>
-
-#include <util/system/info.h>
-#include <library/cpp/deprecated/atomic/atomic.h>
-#include <util/system/align.h>
-
-#include <contrib/libs/linuxvdso/interface.h>
-
-#if (defined(_i386_) || defined(_x86_64_)) && defined(_linux_)
-#define HAVE_VDSO_GETCPU 1
-#include <contrib/libs/linuxvdso/interface.h>
-static int (*FastGetCpu)(unsigned* cpu, unsigned* node, void* unused);
-#endif
-
-#if defined(_unix_)
-#include <sched.h>
-#elif defined(_win_)
-#include <WinBase.h>
-#else
-#error NO IMPLEMENTATION FOR THE PLATFORM
-#endif
-
-const char TMemoryLog::DEFAULT_LAST_MARK[16] = {
- 'c',
- 'b',
- '7',
- 'B',
- '6',
- '8',
- 'a',
- '8',
- 'A',
- '5',
- '6',
- '1',
- '6',
- '4',
- '5',
- '\n',
-};
-
-const char TMemoryLog::CLEAR_MARK[16] = {
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- ' ',
- '\n',
-};
-
-unsigned TMemoryLog::GetSelfCpu() noexcept {
-#if defined(_unix_)
-#if HAVE_VDSO_GETCPU
- unsigned cpu;
- if (Y_LIKELY(FastGetCpu != nullptr)) {
- auto result = FastGetCpu(&cpu, nullptr, nullptr);
- Y_ABORT_UNLESS(result == 0);
- return cpu;
- } else {
- return 0;
- }
-
-#elif defined(_x86_64_) || defined(_i386_)
-
-#define CPUID(func, eax, ebx, ecx, edx) \
- __asm__ __volatile__( \
- "cpuid" \
- : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) \
- : "a"(func));
-
- int a = 0, b = 0, c = 0, d = 0;
- CPUID(0x1, a, b, c, d);
- int acpiID = (b >> 24);
- return acpiID;
-
-#elif defined(__CNUC__)
- return sched_getcpu();
-#else
- return 0;
-#endif
-
-#elif defined(_win_)
- return GetCurrentProcessorNumber();
-#else
- return 0;
-#endif
-}
-
-TMemoryLog* TMemoryLog::MemLogBuffer = nullptr;
-Y_POD_THREAD(TThread::TId)
-TMemoryLog::LogThreadId;
-char* TMemoryLog::LastMarkIsHere = nullptr;
-
-std::atomic<bool> TMemoryLog::PrintLastMark(true);
-
-TMemoryLog::TMemoryLog(size_t totalSize, size_t grainSize)
- : GrainSize(grainSize)
- , FreeGrains(DEFAULT_TOTAL_SIZE / DEFAULT_GRAIN_SIZE * 2)
- , Buf(totalSize)
-{
- Y_ABORT_UNLESS(DEFAULT_TOTAL_SIZE % DEFAULT_GRAIN_SIZE == 0);
- NumberOfGrains = DEFAULT_TOTAL_SIZE / DEFAULT_GRAIN_SIZE;
-
- for (size_t i = 0; i < NumberOfGrains; ++i) {
- new (GetGrain(i)) TGrain;
- }
-
- NumberOfCpus = NSystemInfo::NumberOfCpus();
- Y_ABORT_UNLESS(NumberOfGrains > NumberOfCpus);
- ActiveGrains.Reset(new TGrain*[NumberOfCpus]);
- for (size_t i = 0; i < NumberOfCpus; ++i) {
- ActiveGrains[i] = GetGrain(i);
- }
-
- for (size_t i = NumberOfCpus; i < NumberOfGrains; ++i) {
- FreeGrains.StubbornPush(GetGrain(i));
- }
-
-#if HAVE_VDSO_GETCPU
- auto vdsoFunc = (decltype(FastGetCpu))
- NVdso::Function("__vdso_getcpu", "LINUX_2.6");
- AtomicSet(FastGetCpu, vdsoFunc);
-#endif
-}
-
-void* TMemoryLog::GetWriteBuffer(size_t amount) noexcept {
- // alignment required by NoCacheMemcpy
- amount = AlignUp<size_t>(amount, MemcpyAlignment);
-
- for (ui16 tries = MAX_GET_BUFFER_TRIES; tries-- > 0;) {
- auto myCpu = GetSelfCpu();
-
- TGrain* grain = AtomicGet(ActiveGrains[myCpu]);
-
- if (grain != nullptr) {
- auto mine = AtomicGetAndAdd(grain->WritePointer, amount);
- if (mine + amount <= GrainSize - sizeof(TGrain)) {
- return &grain->Data[mine];
- }
-
- if (!AtomicCas(&ActiveGrains[myCpu], 0, grain)) {
- continue;
- }
-
- FreeGrains.StubbornPush(grain);
- }
-
- grain = (TGrain*)FreeGrains.Pop();
-
- if (grain == nullptr) {
- return nullptr;
- }
-
- grain->WritePointer = 0;
-
- if (!AtomicCas(&ActiveGrains[myCpu], grain, 0)) {
- FreeGrains.StubbornPush(grain);
- continue;
- }
- }
-
- return nullptr;
-}
-
-void ClearAlignedTail(char* tail) noexcept {
- auto aligned = AlignUp(tail, TMemoryLog::MemcpyAlignment);
- if (aligned > tail) {
- memset(tail, 0, aligned - tail);
- }
-}
-
-#if defined(_x86_64_) || defined(_i386_)
-#include <xmmintrin.h>
-// the main motivation is not poluting CPU cache
-NO_SANITIZE_THREAD
-void NoCacheMemcpy(char* dst, const char* src, size_t size) noexcept {
- while (size >= sizeof(__m128) * 2) {
- __m128 a = _mm_load_ps((float*)(src + 0 * sizeof(__m128)));
- __m128 b = _mm_load_ps((float*)(src + 1 * sizeof(__m128)));
- _mm_stream_ps((float*)(dst + 0 * sizeof(__m128)), a);
- _mm_stream_ps((float*)(dst + 1 * sizeof(__m128)), b);
-
- size -= sizeof(__m128) * 2;
- src += sizeof(__m128) * 2;
- dst += sizeof(__m128) * 2;
- }
- memcpy(dst, src, size);
-}
-
-NO_SANITIZE_THREAD
-void NoWCacheMemcpy(char* dst, const char* src, size_t size) noexcept {
- constexpr ui16 ITEMS_COUNT = 1024;
- alignas(TMemoryLog::MemcpyAlignment) __m128 buf[ITEMS_COUNT];
- while (size >= sizeof(buf)) {
- memcpy(&buf, src, sizeof(buf));
-
- for (ui16 i = 0; i < ITEMS_COUNT; ++i) {
- _mm_stream_ps((float*)dst, buf[i]);
- dst += sizeof(__m128);
- }
-
- size -= sizeof(buf);
- src += sizeof(buf);
- }
-
- memcpy(&buf, src, size);
- // no problem to copy few bytes more
- size = AlignUp(size, sizeof(__m128));
- for (ui16 i = 0; i < size / sizeof(__m128); ++i) {
- _mm_stream_ps((float*)dst, buf[i]);
- dst += sizeof(__m128);
- }
-}
-
-#endif
-
-NO_SANITIZE_THREAD
-char* BareMemLogWrite(const char* begin, size_t msgSize, bool isLast) noexcept {
- bool lastMark =
- isLast && TMemoryLog::PrintLastMark.load(std::memory_order_acquire);
- size_t amount = lastMark ? msgSize + TMemoryLog::LAST_MARK_SIZE : msgSize;
-
- char* buffer = (char*)TMemoryLog::GetWriteBufferStatic(amount);
- if (buffer == nullptr) {
- return nullptr;
- }
-
-#if defined(_x86_64_) || defined(_i386_)
- if (AlignDown(begin, TMemoryLog::MemcpyAlignment) == begin) {
- NoCacheMemcpy(buffer, begin, msgSize);
- } else {
- NoWCacheMemcpy(buffer, begin, msgSize);
- }
-#else
- memcpy(buffer, begin, msgSize);
-#endif
-
- if (lastMark) {
- TMemoryLog::ChangeLastMark(buffer + msgSize);
- }
-
- ClearAlignedTail(buffer + amount);
- return buffer;
-}
-
-NO_SANITIZE_THREAD
-bool MemLogWrite(const char* begin, size_t msgSize, bool addLF) noexcept {
- bool lastMark = TMemoryLog::PrintLastMark.load(std::memory_order_acquire);
- size_t amount = lastMark ? msgSize + TMemoryLog::LAST_MARK_SIZE : msgSize;
-
- // Let's construct prolog with timestamp and thread id
- auto threadId = TMemoryLog::GetTheadId();
-
- // alignment required by NoCacheMemcpy
- // check for format for snprintf
- constexpr size_t prologSize = 48;
- alignas(TMemoryLog::MemcpyAlignment) char prolog[prologSize + 1];
- Y_ABORT_UNLESS(AlignDown(&prolog, TMemoryLog::MemcpyAlignment) == &prolog);
-
- int snprintfResult = snprintf(prolog, prologSize + 1,
- "TS %020" PRIu64 " TI %020" PRIu64 " ", GetCycleCountFast(), threadId);
-
- if (snprintfResult < 0) {
- return false;
- }
- Y_ABORT_UNLESS(snprintfResult == prologSize);
-
- amount += prologSize;
- if (addLF) {
- ++amount; // add 1 byte for \n at the end of the message
- }
-
- char* buffer = (char*)TMemoryLog::GetWriteBufferStatic(amount);
- if (buffer == nullptr) {
- return false;
- }
-
-#if defined(_x86_64_) || defined(_i386_)
- // warning: copy prolog first to avoid corruption of the message
- // by prolog tail
- NoCacheMemcpy(buffer, prolog, prologSize);
- if (AlignDown(begin + prologSize, TMemoryLog::MemcpyAlignment) == begin + prologSize) {
- NoCacheMemcpy(buffer + prologSize, begin, msgSize);
- } else {
- NoWCacheMemcpy(buffer + prologSize, begin, msgSize);
- }
-#else
- memcpy(buffer, prolog, prologSize);
- memcpy(buffer + prologSize, begin, msgSize);
-#endif
-
- if (addLF) {
- buffer[prologSize + msgSize] = '\n';
- }
-
- if (lastMark) {
- TMemoryLog::ChangeLastMark(buffer + prologSize + msgSize + (int)addLF);
- }
-
- ClearAlignedTail(buffer + amount);
- return true;
-}
-
-NO_SANITIZE_THREAD
-void TMemoryLog::ChangeLastMark(char* buffer) noexcept {
- memcpy(buffer, DEFAULT_LAST_MARK, LAST_MARK_SIZE);
- auto oldMark = AtomicSwap(&LastMarkIsHere, buffer);
- if (Y_LIKELY(oldMark != nullptr)) {
- memcpy(oldMark, CLEAR_MARK, LAST_MARK_SIZE);
- }
- if (AtomicGet(LastMarkIsHere) != buffer) {
- memcpy(buffer, CLEAR_MARK, LAST_MARK_SIZE);
- AtomicBarrier();
- }
-}
-
-bool MemLogVPrintF(const char* format, va_list params) noexcept {
- auto logger = TMemoryLog::GetMemoryLogger();
- if (logger == nullptr) {
- return false;
- }
-
- auto threadId = TMemoryLog::GetTheadId();
-
- // alignment required by NoCacheMemcpy
- alignas(TMemoryLog::MemcpyAlignment) char buf[TMemoryLog::MAX_MESSAGE_SIZE];
- Y_ABORT_UNLESS(AlignDown(&buf, TMemoryLog::MemcpyAlignment) == &buf);
-
- int prologSize = snprintf(buf,
- TMemoryLog::MAX_MESSAGE_SIZE - 2,
- "TS %020" PRIu64 " TI %020" PRIu64 " ",
- GetCycleCountFast(),
- threadId);
-
- if (Y_UNLIKELY(prologSize < 0)) {
- return false;
- }
- Y_ABORT_UNLESS((ui32)prologSize <= TMemoryLog::MAX_MESSAGE_SIZE);
-
- int add = vsnprintf(
- &buf[prologSize],
- TMemoryLog::MAX_MESSAGE_SIZE - prologSize - 2,
- format, params);
-
- if (Y_UNLIKELY(add < 0)) {
- return false;
- }
- Y_ABORT_UNLESS(add >= 0);
- auto totalSize = prologSize + add;
-
- buf[totalSize++] = '\n';
- Y_ABORT_UNLESS((ui32)totalSize <= TMemoryLog::MAX_MESSAGE_SIZE);
-
- return BareMemLogWrite(buf, totalSize) != nullptr;
-}
diff --git a/library/cpp/actors/memory_log/memlog.h b/library/cpp/actors/memory_log/memlog.h
deleted file mode 100644
index bf4e115c49..0000000000
--- a/library/cpp/actors/memory_log/memlog.h
+++ /dev/null
@@ -1,211 +0,0 @@
-#pragma once
-
-#include <library/cpp/threading/queue/mpmc_unordered_ring.h>
-#include <util/generic/string.h>
-#include <util/string/printf.h>
-#include <util/system/datetime.h>
-#include <util/system/thread.h>
-#include <util/system/types.h>
-#include <library/cpp/deprecated/atomic/atomic.h>
-#include <util/system/align.h>
-#include <util/system/tls.h>
-
-#include <atomic>
-#include <cstdio>
-
-#ifdef _win_
-#include <util/system/winint.h>
-#endif
-
-#ifndef NO_SANITIZE_THREAD
-#define NO_SANITIZE_THREAD
-#if defined(__has_feature)
-#if __has_feature(thread_sanitizer)
-#undef NO_SANITIZE_THREAD
-#define NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
-#endif
-#endif
-#endif
-
-class TMemoryLog {
-public:
- static constexpr size_t DEFAULT_TOTAL_SIZE = 10 * 1024 * 1024;
- static constexpr size_t DEFAULT_GRAIN_SIZE = 1024 * 64;
- static constexpr size_t MAX_MESSAGE_SIZE = 1024;
- static constexpr ui16 MAX_GET_BUFFER_TRIES = 4;
- static constexpr ui16 MemcpyAlignment = 16;
-
- // search for cb7B68a8A561645
- static const char DEFAULT_LAST_MARK[16];
- static const char CLEAR_MARK[16];
-
- static constexpr size_t LAST_MARK_SIZE = sizeof(DEFAULT_LAST_MARK);
-
- inline static TMemoryLog* GetMemoryLogger() noexcept {
- return AtomicGet(MemLogBuffer);
- }
-
- void* GetWriteBuffer(size_t amount) noexcept;
-
- inline static void* GetWriteBufferStatic(size_t amount) noexcept {
- auto logger = GetMemoryLogger();
- if (logger == nullptr) {
- return nullptr;
- }
- return logger->GetWriteBuffer(amount);
- }
-
- size_t GetGlobalBufferSize() const noexcept {
- return Buf.GetSize();
- }
-
- inline static void CreateMemoryLogBuffer(
- size_t totalSize = DEFAULT_TOTAL_SIZE,
- size_t grainSize = DEFAULT_GRAIN_SIZE)
- Y_COLD {
- if (AtomicGet(MemLogBuffer) != nullptr) {
- return;
- }
-
- AtomicSet(MemLogBuffer, new TMemoryLog(totalSize, grainSize));
- }
-
- static std::atomic<bool> PrintLastMark;
-
- // buffer must be at least 16 bytes
- static void ChangeLastMark(char* buffer) noexcept;
-
- inline static TThread::TId GetTheadId() noexcept {
- if (LogThreadId == 0) {
- LogThreadId = TThread::CurrentThreadId();
- }
- return LogThreadId;
- }
-
-private:
- TMemoryLog(size_t totalSize, size_t grainSize) Y_COLD;
-
- struct TGrain {
- TAtomic WritePointer = 0;
- char Padding[MemcpyAlignment - sizeof(TAtomic)];
- char Data[];
- };
-
- size_t NumberOfCpus;
- size_t GrainSize;
- size_t NumberOfGrains;
- TArrayPtr<TGrain*> ActiveGrains;
- NThreading::TMPMCUnorderedRing FreeGrains;
-
- TGrain* GetGrain(size_t grainIndex) const noexcept {
- return (TGrain*)((char*)GetGlobalBuffer() + GrainSize * grainIndex);
- }
-
- class TMMapArea {
- public:
- TMMapArea(size_t amount) Y_COLD {
- MMap(amount);
- }
-
- TMMapArea(const TMMapArea&) = delete;
- TMMapArea& operator=(const TMMapArea& copy) = delete;
-
- TMMapArea(TMMapArea&& move) Y_COLD {
- BufPtr = move.BufPtr;
- Size = move.Size;
-
- move.BufPtr = nullptr;
- move.Size = 0;
- }
-
- TMMapArea& operator=(TMMapArea&& move) Y_COLD {
- BufPtr = move.BufPtr;
- Size = move.Size;
-
- move.BufPtr = nullptr;
- move.Size = 0;
- return *this;
- }
-
- void Reset(size_t amount) Y_COLD {
- MUnmap();
- MMap(amount);
- }
-
- ~TMMapArea() noexcept Y_COLD {
- MUnmap();
- }
-
- size_t GetSize() const noexcept {
- return Size;
- }
-
- void* GetPtr() const noexcept {
- return BufPtr;
- }
-
- private:
- void* BufPtr;
- size_t Size;
-#ifdef _win_
- HANDLE Mapping;
-#endif
-
- void MMap(size_t amount);
- void MUnmap();
- };
-
- TMMapArea Buf;
-
- void* GetGlobalBuffer() const noexcept {
- return Buf.GetPtr();
- }
-
- static unsigned GetSelfCpu() noexcept;
-
- static TMemoryLog* MemLogBuffer;
- static Y_POD_THREAD(TThread::TId) LogThreadId;
- static char* LastMarkIsHere;
-};
-
-// it's no use of sanitizing this function
-NO_SANITIZE_THREAD
-char* BareMemLogWrite(
- const char* begin, size_t msgSize, bool isLast = true) noexcept;
-
-// it's no use of sanitizing this function
-NO_SANITIZE_THREAD
-bool MemLogWrite(
- const char* begin, size_t msgSize, bool addLF = false) noexcept;
-
-Y_WRAPPER inline bool MemLogWrite(const char* begin, const char* end) noexcept {
- if (end <= begin) {
- return false;
- }
-
- size_t msgSize = end - begin;
- return MemLogWrite(begin, msgSize);
-}
-
-template <typename TObj>
-bool MemLogWriteStruct(const TObj* obj) noexcept {
- auto begin = (const char*)(const void*)obj;
- return MemLogWrite(begin, begin + sizeof(TObj));
-}
-
-Y_PRINTF_FORMAT(1, 0)
-bool MemLogVPrintF(const char* format, va_list params) noexcept;
-
-Y_PRINTF_FORMAT(1, 2)
-Y_WRAPPER
-inline bool MemLogPrintF(const char* format, ...) noexcept {
- va_list params;
- va_start(params, format);
- auto result = MemLogVPrintF(format, params);
- va_end(params);
- return result;
-}
-
-Y_WRAPPER inline bool MemLogWriteNullTerm(const char* str) noexcept {
- return MemLogWrite(str, strlen(str));
-}
diff --git a/library/cpp/actors/memory_log/mmap.cpp b/library/cpp/actors/memory_log/mmap.cpp
deleted file mode 100644
index 1fe734235e..0000000000
--- a/library/cpp/actors/memory_log/mmap.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-#include "memlog.h"
-
-#if defined(_unix_)
-#include <sys/mman.h>
-#elif defined(_win_)
-#include <util/system/winint.h>
-#else
-#error NO IMPLEMENTATION FOR THE PLATFORM
-#endif
-
-void TMemoryLog::TMMapArea::MMap(size_t amount) {
- Y_ABORT_UNLESS(amount > 0);
-
-#if defined(_unix_)
- constexpr int mmapProt = PROT_READ | PROT_WRITE;
-#if defined(_linux_)
- constexpr int mmapFlags = MAP_PRIVATE | MAP_ANON | MAP_POPULATE;
-#else
- constexpr int mmapFlags = MAP_PRIVATE | MAP_ANON;
-#endif
-
- BufPtr = ::mmap(nullptr, amount, mmapProt, mmapFlags, -1, 0);
- if (BufPtr == MAP_FAILED) {
- throw std::bad_alloc();
- }
-
-#elif defined(_win_)
- Mapping = ::CreateFileMapping(
- (HANDLE)-1, nullptr, PAGE_READWRITE, 0, amount, nullptr);
- if (Mapping == NULL) {
- throw std::bad_alloc();
- }
- BufPtr = ::MapViewOfFile(Mapping, FILE_MAP_WRITE, 0, 0, amount);
- if (BufPtr == NULL) {
- throw std::bad_alloc();
- }
-#endif
-
- Size = amount;
-}
-
-void TMemoryLog::TMMapArea::MUnmap() {
- if (BufPtr == nullptr) {
- return;
- }
-
-#if defined(_unix_)
- int result = ::munmap(BufPtr, Size);
- Y_ABORT_UNLESS(result == 0);
-
-#elif defined(_win_)
- BOOL result = ::UnmapViewOfFile(BufPtr);
- Y_ABORT_UNLESS(result != 0);
-
- result = ::CloseHandle(Mapping);
- Y_ABORT_UNLESS(result != 0);
-
- Mapping = 0;
-#endif
-
- BufPtr = nullptr;
- Size = 0;
-}
diff --git a/library/cpp/actors/memory_log/ya.make b/library/cpp/actors/memory_log/ya.make
deleted file mode 100644
index ae766a5464..0000000000
--- a/library/cpp/actors/memory_log/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-LIBRARY()
-
-SRCS(
- memlog.cpp
- memlog.h
- mmap.cpp
-)
-
-PEERDIR(
- library/cpp/threading/queue
- contrib/libs/linuxvdso
- library/cpp/deprecated/atomic
-)
-
-END()
diff --git a/library/cpp/actors/prof/CMakeLists.darwin-arm64.txt b/library/cpp/actors/prof/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index c641cf5a52..0000000000
--- a/library/cpp/actors/prof/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-prof)
-target_link_libraries(cpp-actors-prof PUBLIC
- contrib-libs-cxxsupp
- yutil
- libs-tcmalloc-malloc_extension
- library-cpp-charset
- cpp-containers-atomizer
-)
-target_sources(cpp-actors-prof PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/tag.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/tcmalloc.cpp
-)
diff --git a/library/cpp/actors/prof/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/prof/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index c641cf5a52..0000000000
--- a/library/cpp/actors/prof/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-prof)
-target_link_libraries(cpp-actors-prof PUBLIC
- contrib-libs-cxxsupp
- yutil
- libs-tcmalloc-malloc_extension
- library-cpp-charset
- cpp-containers-atomizer
-)
-target_sources(cpp-actors-prof PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/tag.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/tcmalloc.cpp
-)
diff --git a/library/cpp/actors/prof/CMakeLists.linux-aarch64.txt b/library/cpp/actors/prof/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index fa76970f57..0000000000
--- a/library/cpp/actors/prof/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-prof)
-target_link_libraries(cpp-actors-prof PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- libs-tcmalloc-malloc_extension
- library-cpp-charset
- cpp-containers-atomizer
-)
-target_sources(cpp-actors-prof PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/tag.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/tcmalloc.cpp
-)
diff --git a/library/cpp/actors/prof/CMakeLists.linux-x86_64.txt b/library/cpp/actors/prof/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index fa76970f57..0000000000
--- a/library/cpp/actors/prof/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-prof)
-target_link_libraries(cpp-actors-prof PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- libs-tcmalloc-malloc_extension
- library-cpp-charset
- cpp-containers-atomizer
-)
-target_sources(cpp-actors-prof PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/tag.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/tcmalloc.cpp
-)
diff --git a/library/cpp/actors/prof/CMakeLists.txt b/library/cpp/actors/prof/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/prof/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/prof/CMakeLists.windows-x86_64.txt b/library/cpp/actors/prof/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index c641cf5a52..0000000000
--- a/library/cpp/actors/prof/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-prof)
-target_link_libraries(cpp-actors-prof PUBLIC
- contrib-libs-cxxsupp
- yutil
- libs-tcmalloc-malloc_extension
- library-cpp-charset
- cpp-containers-atomizer
-)
-target_sources(cpp-actors-prof PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/tag.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/tcmalloc.cpp
-)
diff --git a/library/cpp/actors/prof/tag.cpp b/library/cpp/actors/prof/tag.cpp
deleted file mode 100644
index 99248a135f..0000000000
--- a/library/cpp/actors/prof/tag.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-#include "tag.h"
-#include "tcmalloc.h"
-
-#include <library/cpp/charset/ci_string.h>
-#include <library/cpp/containers/atomizer/atomizer.h>
-#include <library/cpp/malloc/api/malloc.h>
-
-#if defined(PROFILE_MEMORY_ALLOCATIONS)
-#include <library/cpp/lfalloc/dbg_info/dbg_info.h>
-#include <library/cpp/ytalloc/api/ytalloc.h>
-#include <library/cpp/yt/memory/memory_tag.h>
-#endif
-
-#include <util/generic/singleton.h>
-#include <util/generic/string.h>
-#include <util/generic/vector.h>
-#include <util/system/mutex.h>
-#include <library/cpp/actors/util/local_process_key.h>
-#include <library/cpp/actors/actor_type/index_constructor.h>
-
-namespace NProfiling {
- class TStringAtoms {
- private:
- TMutex Mutex;
- atomizer<ci_hash, ci_equal_to> Tags;
-
- public:
- static TStringAtoms& Instance() {
- return *Singleton<TStringAtoms>();
- }
-
- ui32 MakeTag(const char* s) {
- Y_ABORT_UNLESS(s);
- with_lock (Mutex) {
- return Tags.string_to_atom(s);
- }
- }
-
- ui32 MakeTags(const TVector<const char*>& ss) {
- Y_ABORT_UNLESS(ss);
- with_lock (Mutex) {
- ui32 baseTag = Tags.string_to_atom(ss[0]);
- ui32 nextTag = baseTag + 1;
- for (auto i = ss.begin() + 1; i != ss.end(); ++i, ++nextTag) {
- Y_ABORT_UNLESS(*i);
- ui32 ctag = Tags.string_to_atom(*i);
- Y_ABORT_UNLESS(ctag == nextTag);
- }
- return baseTag;
- }
- }
-
- const char* GetTag(ui32 tag) const {
- with_lock (Mutex) {
- return Tags.get_atom_name(tag);
- }
- }
-
- size_t GetTagsCount() const {
- with_lock (Mutex) {
- return Tags.size();
- }
- }
- };
-
- ui32 MakeTag(const char* s) {
- return TStringAtoms::Instance().MakeTag(s);
- }
-
- ui32 MakeTags(const TVector<const char*>& ss) {
- return TStringAtoms::Instance().MakeTags(ss);
- }
-
- const char* GetTag(ui32 tag) {
- return TStringAtoms::Instance().GetTag(tag);
- }
-
- size_t GetTagsCount() {
- return TStringAtoms::Instance().GetTagsCount();
- }
-
- static ui32 SetThreadAllocTag_Default(ui32 tag) {
- Y_UNUSED(tag);
- return 0;
- }
-
-#if defined(PROFILE_MEMORY_ALLOCATIONS)
- static ui32 SetThreadAllocTag_YT(ui32 tag) {
- auto prev = NYT::GetCurrentMemoryTag();
- NYT::SetCurrentMemoryTag(tag);
- return prev;
- }
-
- static TSetThreadAllocTag* SetThreadAllocTagFn() {
- const auto& info = NMalloc::MallocInfo();
-
- TStringBuf name(info.Name);
- if (name.StartsWith("lf")) {
- return (TSetThreadAllocTag*)NAllocDbg::SetThreadAllocTag;
- } else if (name.StartsWith("yt")) {
- return SetThreadAllocTag_YT;
- } else if (name.StartsWith("tc")) {
- return SetTCMallocThreadAllocTag;
- } else {
- return SetThreadAllocTag_Default;
- }
- }
-#else
- static TSetThreadAllocTag* SetThreadAllocTagFn() {
- const auto& info = NMalloc::MallocInfo();
-
- TStringBuf name(info.Name);
- if (name.StartsWith("tc")) {
- return SetTCMallocThreadAllocTag;
- } else {
- return SetThreadAllocTag_Default;
- }
- }
-#endif
-
- TSetThreadAllocTag* SetThreadAllocTag = SetThreadAllocTagFn();
-}
-
-TMemoryProfileGuard::TMemoryProfileGuard(const TString& id)
- : Id(id)
-{
- NProfiling::TMemoryTagScope::Reset(TLocalProcessKeyState<NActors::TActorActivityTag>::GetInstance().Register(Id + "-Start"));
-}
-
-TMemoryProfileGuard::~TMemoryProfileGuard() {
- NProfiling::TMemoryTagScope::Reset(TLocalProcessKeyState<NActors::TActorActivityTag>::GetInstance().Register(Id + "-Finish"));
-}
diff --git a/library/cpp/actors/prof/tag.h b/library/cpp/actors/prof/tag.h
deleted file mode 100644
index 1624d9d1e0..0000000000
--- a/library/cpp/actors/prof/tag.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#pragma once
-
-#include <util/generic/string.h>
-#include <util/generic/noncopyable.h>
-#include <util/generic/vector.h>
-
-/*
- Common registry for tagging memory profiler.
- Register a new tag with MakeTag using a unique string.
- Use registered tags with SetThreadAllocTag function in allocator API.
-*/
-
-namespace NProfiling {
- ui32 MakeTag(const char* s);
-
- // Make only unique tags. Y_ABORT_UNLESS inside.
- ui32 MakeTags(const TVector<const char*>& ss);
-
- const char* GetTag(ui32 tag);
- size_t GetTagsCount();
-
- using TSetThreadAllocTag = ui32(ui32 tag);
- extern TSetThreadAllocTag* SetThreadAllocTag;
-
- class TMemoryTagScope {
- public:
- explicit TMemoryTagScope(ui32 tag)
- : RestoreTag(SetThreadAllocTag(tag))
- {
- }
-
- explicit TMemoryTagScope(const char* tagName) {
- ui32 newTag = MakeTag(tagName);
- RestoreTag = SetThreadAllocTag(newTag);
- }
-
- TMemoryTagScope(TMemoryTagScope&& move)
- : RestoreTag(move.RestoreTag)
- , Released(move.Released)
- {
- move.Released = true;
- }
-
- TMemoryTagScope& operator=(TMemoryTagScope&& move) {
- RestoreTag = move.RestoreTag;
- Released = move.Released;
- move.Released = true;
- return *this;
- }
-
- static void Reset(ui32 tag) {
- SetThreadAllocTag(tag);
- }
-
- void Release() {
- if (!Released) {
- SetThreadAllocTag(RestoreTag);
- Released = true;
- }
- }
-
- ~TMemoryTagScope() {
- if (!Released) {
- SetThreadAllocTag(RestoreTag);
- }
- }
-
- protected:
- TMemoryTagScope(const TMemoryTagScope&) = delete;
- void operator=(const TMemoryTagScope&) = delete;
-
- ui32 RestoreTag = 0;
- bool Released = false;
- };
-}
-
-class TMemoryProfileGuard: TNonCopyable {
-private:
- const TString Id;
-public:
- TMemoryProfileGuard(const TString& id);
- ~TMemoryProfileGuard();
-
-};
diff --git a/library/cpp/actors/prof/tcmalloc.cpp b/library/cpp/actors/prof/tcmalloc.cpp
deleted file mode 100644
index 3d4f203dbb..0000000000
--- a/library/cpp/actors/prof/tcmalloc.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "tcmalloc.h"
-
-#include <contrib/libs/tcmalloc/tcmalloc/malloc_extension.h>
-
-namespace NProfiling {
-
-static thread_local ui32 AllocationTag = 0;
-
-static struct TInitTCMallocCallbacks {
- static void* CreateTag() {
- return reinterpret_cast<void*>(AllocationTag);
- }
- static void* CopyTag(void* tag) {
- return tag;
- }
- static void DestroyTag(void* tag) {
- Y_UNUSED(tag);
- }
-
- TInitTCMallocCallbacks() {
- tcmalloc::MallocExtension::SetSampleUserDataCallbacks(
- CreateTag, CopyTag, DestroyTag);
- }
-} InitTCMallocCallbacks;
-
-ui32 SetTCMallocThreadAllocTag(ui32 tag) {
- ui32 prev = AllocationTag;
- AllocationTag = tag;
- return prev;
-}
-
-}
diff --git a/library/cpp/actors/prof/tcmalloc.h b/library/cpp/actors/prof/tcmalloc.h
deleted file mode 100644
index 659fb4eaf3..0000000000
--- a/library/cpp/actors/prof/tcmalloc.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#include <util/generic/fwd.h>
-
-namespace NProfiling {
-
-ui32 SetTCMallocThreadAllocTag(ui32 tag);
-
-}
diff --git a/library/cpp/actors/prof/ut/CMakeLists.darwin-arm64.txt b/library/cpp/actors/prof/ut/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 44995c4d4b..0000000000
--- a/library/cpp/actors/prof/ut/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-prof-ut)
-target_include_directories(library-cpp-actors-prof-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof
-)
-target_link_libraries(library-cpp-actors-prof-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-prof
-)
-target_link_options(library-cpp-actors-prof-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-prof-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/ut/tag_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-prof-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-prof-ut
- TEST_TARGET
- library-cpp-actors-prof-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-prof-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-prof-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-prof-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-prof-ut)
diff --git a/library/cpp/actors/prof/ut/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/prof/ut/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 0ec56d8762..0000000000
--- a/library/cpp/actors/prof/ut/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-prof-ut)
-target_include_directories(library-cpp-actors-prof-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof
-)
-target_link_libraries(library-cpp-actors-prof-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-prof
-)
-target_link_options(library-cpp-actors-prof-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-prof-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/ut/tag_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-prof-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-prof-ut
- TEST_TARGET
- library-cpp-actors-prof-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-prof-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-prof-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-prof-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-prof-ut)
diff --git a/library/cpp/actors/prof/ut/CMakeLists.linux-aarch64.txt b/library/cpp/actors/prof/ut/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 591055b744..0000000000
--- a/library/cpp/actors/prof/ut/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-prof-ut)
-target_include_directories(library-cpp-actors-prof-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof
-)
-target_link_libraries(library-cpp-actors-prof-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-prof
-)
-target_link_options(library-cpp-actors-prof-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-prof-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/ut/tag_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-prof-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-prof-ut
- TEST_TARGET
- library-cpp-actors-prof-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-prof-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-prof-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-prof-ut
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-prof-ut)
diff --git a/library/cpp/actors/prof/ut/CMakeLists.linux-x86_64.txt b/library/cpp/actors/prof/ut/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 7c84eda1b0..0000000000
--- a/library/cpp/actors/prof/ut/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-prof-ut)
-target_include_directories(library-cpp-actors-prof-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof
-)
-target_link_libraries(library-cpp-actors-prof-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-prof
-)
-target_link_options(library-cpp-actors-prof-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-prof-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/ut/tag_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-prof-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-prof-ut
- TEST_TARGET
- library-cpp-actors-prof-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-prof-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-prof-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-prof-ut
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-prof-ut)
diff --git a/library/cpp/actors/prof/ut/CMakeLists.txt b/library/cpp/actors/prof/ut/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/prof/ut/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/prof/ut/CMakeLists.windows-x86_64.txt b/library/cpp/actors/prof/ut/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 3165130380..0000000000
--- a/library/cpp/actors/prof/ut/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-prof-ut)
-target_include_directories(library-cpp-actors-prof-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof
-)
-target_link_libraries(library-cpp-actors-prof-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-prof
-)
-target_sources(library-cpp-actors-prof-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/prof/ut/tag_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-prof-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-prof-ut
- TEST_TARGET
- library-cpp-actors-prof-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-prof-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-prof-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-prof-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-prof-ut)
diff --git a/library/cpp/actors/prof/ut/tag_ut.cpp b/library/cpp/actors/prof/ut/tag_ut.cpp
deleted file mode 100644
index accf3921ab..0000000000
--- a/library/cpp/actors/prof/ut/tag_ut.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "tag.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-
-using namespace NProfiling;
-
-class TAtomTagsTest: public TTestBase {
-private:
- UNIT_TEST_SUITE(TAtomTagsTest);
- UNIT_TEST(Test_MakeTag);
- UNIT_TEST(Test_Make2Tags);
- UNIT_TEST(Test_MakeTagTwice);
-
- UNIT_TEST(Test_MakeAndGetTag);
-
- UNIT_TEST(Test_MakeVector);
- UNIT_TEST_SUITE_END();
-
-public:
- void Test_MakeTag();
- void Test_Make2Tags();
- void Test_MakeTagTwice();
- void Test_MakeAndGetTag();
- void Test_MakeVector();
-};
-
-UNIT_TEST_SUITE_REGISTRATION(TAtomTagsTest);
-
-void TAtomTagsTest::Test_MakeTag() {
- ui32 tag = MakeTag("a tag");
- UNIT_ASSERT(tag != 0);
-}
-
-void TAtomTagsTest::Test_Make2Tags() {
- ui32 tag1 = MakeTag("a tag 1");
- ui32 tag2 = MakeTag("a tag 2");
- UNIT_ASSERT(tag1 != 0);
- UNIT_ASSERT(tag2 != 0);
- UNIT_ASSERT(tag1 != tag2);
-}
-
-void TAtomTagsTest::Test_MakeTagTwice() {
- ui32 tag1 = MakeTag("a tag twice");
- ui32 tag2 = MakeTag("a tag twice");
- UNIT_ASSERT(tag1 != 0);
- UNIT_ASSERT(tag1 == tag2);
-}
-
-void TAtomTagsTest::Test_MakeAndGetTag() {
- const char* makeStr = "tag to get";
- ui32 tag = MakeTag(makeStr);
- const char* tagStr = GetTag(tag);
- UNIT_ASSERT_STRINGS_EQUAL(makeStr, tagStr);
-}
-
-void TAtomTagsTest::Test_MakeVector() {
- TVector<const char*> strs = {
- "vector tag 0",
- "vector tag 1",
- "vector tag 3",
- "vector tag 4"};
- ui32 baseTag = MakeTags(strs);
- UNIT_ASSERT(baseTag != 0);
- for (ui32 i = 0; i < strs.size(); ++i) {
- const char* str = GetTag(baseTag + i);
- UNIT_ASSERT_STRINGS_EQUAL(str, strs[i]);
- }
-}
diff --git a/library/cpp/actors/prof/ut/ya.make b/library/cpp/actors/prof/ut/ya.make
deleted file mode 100644
index e439856698..0000000000
--- a/library/cpp/actors/prof/ut/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-UNITTEST_FOR(library/cpp/actors/prof)
-
-SRCS(
- tag_ut.cpp
-)
-
-END()
diff --git a/library/cpp/actors/prof/ya.make b/library/cpp/actors/prof/ya.make
deleted file mode 100644
index 4bae10a443..0000000000
--- a/library/cpp/actors/prof/ya.make
+++ /dev/null
@@ -1,28 +0,0 @@
-LIBRARY()
-
-SRCS(
- tag.cpp
- tcmalloc.cpp
-)
-
-PEERDIR(
- contrib/libs/tcmalloc/malloc_extension
- library/cpp/charset
- library/cpp/containers/atomizer
-)
-
-IF (PROFILE_MEMORY_ALLOCATIONS)
- CFLAGS(-DPROFILE_MEMORY_ALLOCATIONS)
- PEERDIR(
- library/cpp/malloc/api
- library/cpp/lfalloc/dbg_info
- library/cpp/ytalloc/api
- library/cpp/yt/memory
- )
-ENDIF()
-
-END()
-
-RECURSE_FOR_TESTS(
- ut
-)
diff --git a/library/cpp/actors/protos/CMakeLists.darwin-arm64.txt b/library/cpp/actors/protos/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index be3257b127..0000000000
--- a/library/cpp/actors/protos/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_library(cpp-actors-protos)
-target_link_libraries(cpp-actors-protos PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-protobuf
-)
-target_proto_messages(cpp-actors-protos PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/actors.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/interconnect.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/services_common.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/unittests.proto
-)
-target_proto_addincls(cpp-actors-protos
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(cpp-actors-protos
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
diff --git a/library/cpp/actors/protos/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/protos/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index be3257b127..0000000000
--- a/library/cpp/actors/protos/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_library(cpp-actors-protos)
-target_link_libraries(cpp-actors-protos PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-protobuf
-)
-target_proto_messages(cpp-actors-protos PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/actors.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/interconnect.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/services_common.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/unittests.proto
-)
-target_proto_addincls(cpp-actors-protos
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(cpp-actors-protos
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
diff --git a/library/cpp/actors/protos/CMakeLists.linux-aarch64.txt b/library/cpp/actors/protos/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index a9da706400..0000000000
--- a/library/cpp/actors/protos/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_library(cpp-actors-protos)
-target_link_libraries(cpp-actors-protos PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-protobuf
-)
-target_proto_messages(cpp-actors-protos PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/actors.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/interconnect.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/services_common.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/unittests.proto
-)
-target_proto_addincls(cpp-actors-protos
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(cpp-actors-protos
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
diff --git a/library/cpp/actors/protos/CMakeLists.linux-x86_64.txt b/library/cpp/actors/protos/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index a9da706400..0000000000
--- a/library/cpp/actors/protos/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_library(cpp-actors-protos)
-target_link_libraries(cpp-actors-protos PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-protobuf
-)
-target_proto_messages(cpp-actors-protos PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/actors.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/interconnect.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/services_common.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/unittests.proto
-)
-target_proto_addincls(cpp-actors-protos
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(cpp-actors-protos
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
diff --git a/library/cpp/actors/protos/CMakeLists.txt b/library/cpp/actors/protos/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/protos/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/protos/CMakeLists.windows-x86_64.txt b/library/cpp/actors/protos/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index be3257b127..0000000000
--- a/library/cpp/actors/protos/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-get_built_tool_path(
- TOOL_protoc_bin
- TOOL_protoc_dependency
- contrib/tools/protoc/bin
- protoc
-)
-get_built_tool_path(
- TOOL_cpp_styleguide_bin
- TOOL_cpp_styleguide_dependency
- contrib/tools/protoc/plugins/cpp_styleguide
- cpp_styleguide
-)
-
-add_library(cpp-actors-protos)
-target_link_libraries(cpp-actors-protos PUBLIC
- contrib-libs-cxxsupp
- yutil
- contrib-libs-protobuf
-)
-target_proto_messages(cpp-actors-protos PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/actors.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/interconnect.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/services_common.proto
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/protos/unittests.proto
-)
-target_proto_addincls(cpp-actors-protos
- ./
- ${CMAKE_SOURCE_DIR}/
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/contrib/libs/protobuf/src
-)
-target_proto_outs(cpp-actors-protos
- --cpp_out=${CMAKE_BINARY_DIR}/
- --cpp_styleguide_out=${CMAKE_BINARY_DIR}/
-)
diff --git a/library/cpp/actors/protos/actors.proto b/library/cpp/actors/protos/actors.proto
deleted file mode 100644
index 329eb998df..0000000000
--- a/library/cpp/actors/protos/actors.proto
+++ /dev/null
@@ -1,41 +0,0 @@
-package NActorsProto;
-option java_package = "ru.yandex.kikimr.proto";
-option java_outer_classname = "NActorsBaseProto";
-
-message TActorId {
- required fixed64 RawX1 = 1;
- required fixed64 RawX2 = 2;
-}
-
-message TTraceId {
- optional bytes Data = 1;
-}
-
-message TCallbackException {
- required TActorId ActorId = 1;
- required string ExceptionMessage = 2;
-}
-
-message TRemoteHttpInfo {
- message TQueryParam {
- optional string Key = 1;
- optional string Value = 2;
- }
-
- message THeader {
- optional string Name = 1;
- optional string Value = 2;
- }
-
- optional uint32 Method = 1; // HTTP_METHOD enum
- optional string Path = 2;
- repeated TQueryParam QueryParams = 3;
- repeated TQueryParam PostParams = 4;
- optional bytes PostContent = 8;
- repeated THeader Headers = 9;
- optional string RemoteAddr = 7;
-
- // for compatibility reasons (incorrect field types merged in 21-4)
- reserved 5;
- reserved 6;
-}
diff --git a/library/cpp/actors/protos/interconnect.proto b/library/cpp/actors/protos/interconnect.proto
deleted file mode 100644
index 0e88f3bce5..0000000000
--- a/library/cpp/actors/protos/interconnect.proto
+++ /dev/null
@@ -1,133 +0,0 @@
-import "library/cpp/actors/protos/actors.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;
-}
-
-message TEvNodeInfo {
- optional uint32 NodeId = 1;
- optional string Address = 2;
- 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;
-}
-
-message THandshakeRequest {
- required uint64 Protocol = 1;
-
- required uint64 ProgramPID = 2;
- required uint64 ProgramStartTime = 3;
- required uint64 Serial = 4;
-
- required uint32 ReceiverNodeId = 5;
- required string SenderActorId = 6;
-
- 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 bool RequestExtendedTraceFmt = 20;
- optional bool RequestExternalDataChannel = 21;
- optional bool RequestXxhash = 24;
- optional bool RequestXdcShuffle = 25;
-
- optional bytes CompatibilityInfo = 22;
-
- optional bytes HandshakeId = 23;
-}
-
-message THandshakeSuccess {
- required uint64 Protocol = 1;
-
- required uint64 ProgramPID = 2;
- required uint64 ProgramStartTime = 3;
- 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 bool UseExtendedTraceFmt = 13;
- optional bool UseExternalDataChannel = 14;
- optional bool UseXxhash = 16;
- optional bool UseXdcShuffle = 17;
-
- optional bytes CompatibilityInfo = 15;
-}
-
-message THandshakeReply {
- optional THandshakeSuccess Success = 1;
- optional string ErrorExplaination = 2;
- optional bool CookieCheckResult = 3;
-}
-
-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
-}
-
-message TContinuationParams {
- optional bytes HandshakeId = 1;
-}
-
-message TExternalDataChannelParams {
- optional bytes HandshakeId = 1;
-}
diff --git a/library/cpp/actors/protos/services_common.proto b/library/cpp/actors/protos/services_common.proto
deleted file mode 100644
index 1191859f03..0000000000
--- a/library/cpp/actors/protos/services_common.proto
+++ /dev/null
@@ -1,22 +0,0 @@
-package NActorsServices;
-option java_package = "ru.yandex.kikimr.proto";
-
-// 0-255 range
-enum EServiceCommon {
- // WARN: This must be the smallest value in the enumeration
-
- GLOBAL = 0;
- INTERCONNECT = 1;
- TEST = 2;
- PROTOCOLS = 3;
- INTERCONNECT_SPEED_TEST = 4;
- INTERCONNECT_STATUS = 5;
- INTERCONNECT_NETWORK = 6;
- INTERCONNECT_SESSION = 7;
- HTTP = 8;
- LOGGER = 9;
-
- // This value is reserved boundary. Is must not be aliased with any values
- // TODO: use reseved values upon protobuf update
- // COMMON_END = 256;
-};
diff --git a/library/cpp/actors/protos/unittests.proto b/library/cpp/actors/protos/unittests.proto
deleted file mode 100644
index 4b1af85e01..0000000000
--- a/library/cpp/actors/protos/unittests.proto
+++ /dev/null
@@ -1,20 +0,0 @@
-option cc_enable_arenas = true;
-
-message TSimple {
- required string Str1 = 1;
- optional string Str2 = 2;
- optional uint64 Number1 = 3;
-}
-
-message TBigMessage {
- repeated TSimple Simples = 1;
- repeated string ManyStr = 2;
- optional string OneMoreStr = 3;
- optional uint64 YANumber = 4;
-}
-
-message TMessageWithPayload {
- optional string Meta = 1;
- repeated uint32 PayloadId = 2;
- repeated bytes SomeData = 3;
-}
diff --git a/library/cpp/actors/protos/ya.make b/library/cpp/actors/protos/ya.make
deleted file mode 100644
index c9139191ec..0000000000
--- a/library/cpp/actors/protos/ya.make
+++ /dev/null
@@ -1,12 +0,0 @@
-PROTO_LIBRARY()
-
-SRCS(
- actors.proto
- interconnect.proto
- services_common.proto
- unittests.proto
-)
-
-EXCLUDE_TAGS(GO_PROTO)
-
-END()
diff --git a/library/cpp/actors/testlib/CMakeLists.darwin-arm64.txt b/library/cpp/actors/testlib/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 4f1c8d01a2..0000000000
--- a/library/cpp/actors/testlib/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-testlib)
-target_link_libraries(cpp-actors-testlib PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- actors-interconnect-mock
- cpp-actors-protos
- library-cpp-random_provider
- library-cpp-time_provider
-)
-target_sources(cpp-actors-testlib PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib/test_runtime.cpp
-)
diff --git a/library/cpp/actors/testlib/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/testlib/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 4f1c8d01a2..0000000000
--- a/library/cpp/actors/testlib/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-testlib)
-target_link_libraries(cpp-actors-testlib PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- actors-interconnect-mock
- cpp-actors-protos
- library-cpp-random_provider
- library-cpp-time_provider
-)
-target_sources(cpp-actors-testlib PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib/test_runtime.cpp
-)
diff --git a/library/cpp/actors/testlib/CMakeLists.linux-aarch64.txt b/library/cpp/actors/testlib/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 40a5c9c26f..0000000000
--- a/library/cpp/actors/testlib/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-testlib)
-target_link_libraries(cpp-actors-testlib PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- actors-interconnect-mock
- cpp-actors-protos
- library-cpp-random_provider
- library-cpp-time_provider
-)
-target_sources(cpp-actors-testlib PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib/test_runtime.cpp
-)
diff --git a/library/cpp/actors/testlib/CMakeLists.linux-x86_64.txt b/library/cpp/actors/testlib/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 40a5c9c26f..0000000000
--- a/library/cpp/actors/testlib/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-testlib)
-target_link_libraries(cpp-actors-testlib PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- actors-interconnect-mock
- cpp-actors-protos
- library-cpp-random_provider
- library-cpp-time_provider
-)
-target_sources(cpp-actors-testlib PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib/test_runtime.cpp
-)
diff --git a/library/cpp/actors/testlib/CMakeLists.txt b/library/cpp/actors/testlib/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/testlib/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/testlib/CMakeLists.windows-x86_64.txt b/library/cpp/actors/testlib/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 4f1c8d01a2..0000000000
--- a/library/cpp/actors/testlib/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-testlib)
-target_link_libraries(cpp-actors-testlib PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- actors-interconnect-mock
- cpp-actors-protos
- library-cpp-random_provider
- library-cpp-time_provider
-)
-target_sources(cpp-actors-testlib PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib/test_runtime.cpp
-)
diff --git a/library/cpp/actors/testlib/decorator_ut.cpp b/library/cpp/actors/testlib/decorator_ut.cpp
deleted file mode 100644
index fe5c769290..0000000000
--- a/library/cpp/actors/testlib/decorator_ut.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-#include "test_runtime.h"
-
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-
-using namespace NActors;
-
-
-Y_UNIT_TEST_SUITE(TesTTestDecorator) {
-
- bool IsVerbose = false;
- void Write(TString msg) {
- if (IsVerbose) {
- Cerr << (TStringBuilder() << msg << Endl);
- }
- }
-
- struct TDyingChecker : TTestDecorator {
- TActorId MasterId;
-
- TDyingChecker(THolder<IActor> &&actor, TActorId masterId)
- : TTestDecorator(std::move(actor))
- , MasterId(masterId)
- {
- Write("TDyingChecker::Construct\n");
- }
-
- virtual ~TDyingChecker() {
- Write("TDyingChecker::~TDyingChecker");
- TActivationContext::Send(new IEventHandle(MasterId, SelfId(), new TEvents::TEvPing()));
- }
-
- bool DoBeforeReceiving(TAutoPtr<IEventHandle> &/*ev*/, const TActorContext &/*ctx*/) override {
- Write("TDyingChecker::DoBeforeReceiving");
- return true;
- }
-
- void DoAfterReceiving(const TActorContext &/*ctx*/) override {
- Write("TDyingChecker::DoAfterReceiving");
- }
- };
-
- struct TTestMasterActor : TActorBootstrapped<TTestMasterActor> {
- friend TActorBootstrapped<TTestMasterActor>;
-
- TSet<TActorId> ActorIds;
- TVector<THolder<IActor>> Actors;
- TActorId EdgeActor;
-
- TTestMasterActor(TVector<THolder<IActor>> &&actors, TActorId edgeActor)
- : TActorBootstrapped()
- , Actors(std::move(actors))
- , EdgeActor(edgeActor)
- {
- }
-
- void Bootstrap()
- {
- Write("Start master actor");
- for (auto &actor : Actors) {
- THolder<IActor> decaratedActor = MakeHolder<TDyingChecker>(std::move(actor), SelfId());
- TActorId id = Register(decaratedActor.Release());
- Write("Register test actor");
- UNIT_ASSERT(ActorIds.insert(id).second);
- }
- Become(&TTestMasterActor::State);
- }
-
- STATEFN(State) {
- auto it = ActorIds.find(ev->Sender);
- UNIT_ASSERT(it != ActorIds.end());
- Write("End test actor");
- ActorIds.erase(it);
- if (!ActorIds) {
- Send(EdgeActor, new TEvents::TEvPing());
- PassAway();
- }
- }
- };
-
- enum {
- Begin = EventSpaceBegin(TEvents::ES_USERSPACE),
- EvWords
- };
-
- struct TEvWords : TEventLocal<TEvWords, EvWords> {
- TVector<TString> Words;
-
- TEvWords()
- : TEventLocal()
- {
- }
- };
-
- struct TFizzBuzzToFooBar : TTestDecorator {
- TFizzBuzzToFooBar(THolder<IActor> &&actor)
- : TTestDecorator(std::move(actor))
- {
- }
-
- bool DoBeforeSending(TAutoPtr<IEventHandle> &ev) override {
- if (ev->Type == TEvents::TSystem::Bootstrap) {
- return true;
- }
- Write("TFizzBuzzToFooBar::DoBeforeSending");
- TEventHandle<TEvWords> *handle = reinterpret_cast<TEventHandle<TEvWords>*>(ev.Get());
- UNIT_ASSERT(handle);
- TEvWords *event = handle->Get();
- TVector<TString> &words = event->Words;
- TStringBuilder wordsMsg;
- for (auto &word : words) {
- wordsMsg << word << ';';
- }
- Write(TStringBuilder() << "Send# " << wordsMsg);
- if (words.size() == 2 && words[0] == "Fizz" && words[1] == "Buzz") {
- words[0] = "Foo";
- words[1] = "Bar";
- }
- return true;
- }
-
- bool DoBeforeReceiving(TAutoPtr<IEventHandle> &/*ev*/, const TActorContext &/*ctx*/) override {
- Write("TFizzBuzzToFooBar::DoBeforeReceiving");
- return true;
- }
-
- void DoAfterReceiving(const TActorContext &/*ctx*/) override {
- Write("TFizzBuzzToFooBar::DoAfterReceiving");
- }
- };
-
- struct TWordEraser : TTestDecorator {
- TString ErasingWord;
-
- TWordEraser(THolder<IActor> &&actor, TString word)
- : TTestDecorator(std::move(actor))
- , ErasingWord(word)
- {
- }
-
- bool DoBeforeSending(TAutoPtr<IEventHandle> &ev) override {
- if (ev->Type == TEvents::TSystem::Bootstrap) {
- return true;
- }
- Write("TWordEraser::DoBeforeSending");
- TEventHandle<TEvWords> *handle = reinterpret_cast<TEventHandle<TEvWords>*>(ev.Get());
- UNIT_ASSERT(handle);
- TEvWords *event = handle->Get();
- TVector<TString> &words = event->Words;
- auto it = Find(words.begin(), words.end(), ErasingWord);
- if (it != words.end()) {
- words.erase(it);
- }
- return true;
- }
-
- bool DoBeforeReceiving(TAutoPtr<IEventHandle> &/*ev*/, const TActorContext &/*ctx*/) override {
- Write("TWordEraser::DoBeforeReceiving");
- return true;
- }
-
- void DoAfterReceiving(const TActorContext &/*ctx*/) override {
- Write("TWordEraser::DoAfterReceiving");
- }
- };
-
- struct TWithoutWordsDroper : TTestDecorator {
- TWithoutWordsDroper(THolder<IActor> &&actor)
- : TTestDecorator(std::move(actor))
- {
- }
-
- bool DoBeforeSending(TAutoPtr<IEventHandle> &ev) override {
- if (ev->Type == TEvents::TSystem::Bootstrap) {
- return true;
- }
- Write("TWithoutWordsDroper::DoBeforeSending");
- TEventHandle<TEvWords> *handle = reinterpret_cast<TEventHandle<TEvWords>*>(ev.Get());
- UNIT_ASSERT(handle);
- TEvWords *event = handle->Get();
- return bool(event->Words);
- }
-
- bool DoBeforeReceiving(TAutoPtr<IEventHandle> &/*ev*/, const TActorContext &/*ctx*/) override {
- Write("TWithoutWordsDroper::DoBeforeReceiving");
- return true;
- }
-
- void DoAfterReceiving(const TActorContext &/*ctx*/) override {
- Write("TWithoutWordsDroper::DoAfterReceiving");
- }
- };
-
- struct TFooBarReceiver : TActorBootstrapped<TFooBarReceiver> {
- TActorId MasterId;
- ui64 Counter = 0;
-
- TFooBarReceiver(TActorId masterId)
- : TActorBootstrapped()
- , MasterId(masterId)
- {
- }
-
- void Bootstrap()
- {
- Become(&TFooBarReceiver::State);
- }
-
- STATEFN(State) {
- TEventHandle<TEvWords> *handle = reinterpret_cast<TEventHandle<TEvWords>*>(ev.Get());
- UNIT_ASSERT(handle);
- UNIT_ASSERT(handle->Sender == MasterId);
- TEvWords *event = handle->Get();
- TVector<TString> &words = event->Words;
- UNIT_ASSERT(words.size() == 2 && words[0] == "Foo" && words[1] == "Bar");
- Write(TStringBuilder() << "Receive# " << Counter + 1 << '/' << 2);
- if (++Counter == 2) {
- PassAway();
- }
- }
- };
-
- struct TFizzBuzzSender : TActorBootstrapped<TFizzBuzzSender> {
- TActorId SlaveId;
-
- TFizzBuzzSender()
- : TActorBootstrapped()
- {
- Write("TFizzBuzzSender::Construct");
- }
-
- void Bootstrap() {
- Write("TFizzBuzzSender::Bootstrap");
- THolder<IActor> actor = MakeHolder<TFooBarReceiver>(SelfId());
- THolder<IActor> decoratedActor = MakeHolder<TDyingChecker>(std::move(actor), SelfId());
- SlaveId = Register(decoratedActor.Release());
- for (ui64 idx = 1; idx <= 30; ++idx) {
- THolder<TEvWords> ev = MakeHolder<TEvWords>();
- if (idx % 3 == 0) {
- ev->Words.push_back("Fizz");
- }
- if (idx % 5 == 0) {
- ev->Words.push_back("Buzz");
- }
- Send(SlaveId, ev.Release());
- Write("TFizzBuzzSender::Send words");
- }
- Become(&TFizzBuzzSender::State);
- }
-
- STATEFN(State) {
- UNIT_ASSERT(ev->Sender == SlaveId);
- PassAway();
- }
- };
-
- struct TCounters {
- ui64 SendedCount = 0;
- ui64 RecievedCount = 0;
- };
-
- struct TCountingDecorator : TTestDecorator {
- TCounters *Counters;
-
- TCountingDecorator(THolder<IActor> &&actor, TCounters *counters)
- : TTestDecorator(std::move(actor))
- , Counters(counters)
- {
- }
-
- bool DoBeforeSending(TAutoPtr<IEventHandle> &ev) override {
- if (ev->Type == TEvents::TSystem::Bootstrap) {
- return true;
- }
- Write("TCountingDecorator::DoBeforeSending");
- Counters->SendedCount++;
- return true;
- }
-
- bool DoBeforeReceiving(TAutoPtr<IEventHandle> &/*ev*/, const TActorContext &/*ctx*/) override {
- Write("TCountingDecorator::DoBeforeReceiving");
- Counters->RecievedCount++;
- return true;
- }
- };
-
- bool ScheduledFilterFunc(NActors::TTestActorRuntimeBase& runtime, TAutoPtr<NActors::IEventHandle>& event,
- TDuration delay, TInstant& deadline) {
- if (runtime.IsScheduleForActorEnabled(event->GetRecipientRewrite())) {
- deadline = runtime.GetTimeProvider()->Now() + delay;
- return false;
- }
- return true;
- }
-
- THolder<IActor> CreateFizzBuzzSender() {
- THolder<IActor> actor = MakeHolder<TFizzBuzzSender>();
- THolder<IActor> foobar = MakeHolder<TFizzBuzzToFooBar>(std::move(actor));
- THolder<IActor> fizzEraser = MakeHolder<TWordEraser>(std::move(foobar), "Fizz");
- THolder<IActor> buzzEraser = MakeHolder<TWordEraser>(std::move(fizzEraser), "Buzz");
- return MakeHolder<TWithoutWordsDroper>(std::move(buzzEraser));
- }
-
- Y_UNIT_TEST(Basic) {
- TTestActorRuntimeBase runtime(1, false);
-
- runtime.SetScheduledEventFilter(&ScheduledFilterFunc);
- runtime.SetEventFilter([](NActors::TTestActorRuntimeBase&, TAutoPtr<NActors::IEventHandle>&) {
- return false;
- });
- runtime.Initialize();
-
- TActorId edgeActor = runtime.AllocateEdgeActor();
- TVector<THolder<IActor>> actors(1);
- actors[0] = CreateFizzBuzzSender();
- //actors[1] = CreateFizzBuzzSender();
- THolder<IActor> testActor = MakeHolder<TTestMasterActor>(std::move(actors), edgeActor);
- Write("Start test");
- runtime.Register(testActor.Release());
-
- TAutoPtr<IEventHandle> handle;
- auto ev = runtime.GrabEdgeEventRethrow<TEvents::TEvPing>(handle);
- UNIT_ASSERT(ev);
- Write("Stop test");
- }
-}
diff --git a/library/cpp/actors/testlib/test_runtime.cpp b/library/cpp/actors/testlib/test_runtime.cpp
deleted file mode 100644
index 18e58c21de..0000000000
--- a/library/cpp/actors/testlib/test_runtime.cpp
+++ /dev/null
@@ -1,1968 +0,0 @@
-#include "test_runtime.h"
-
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/callstack.h>
-#include <library/cpp/actors/core/executor_pool_basic.h>
-#include <library/cpp/actors/core/executor_pool_io.h>
-#include <library/cpp/actors/core/log.h>
-#include <library/cpp/actors/core/scheduler_basic.h>
-#include <library/cpp/actors/util/datetime.h>
-#include <library/cpp/actors/protos/services_common.pb.h>
-#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 <util/generic/maybe.h>
-#include <util/generic/bt_exception.h>
-#include <util/random/mersenne.h>
-#include <util/string/printf.h>
-#include <typeinfo>
-
-bool VERBOSE = false;
-const bool PRINT_EVENT_BODY = false;
-
-namespace {
-
- TString MakeClusterId() {
- pid_t pid = getpid();
- TStringBuilder uuid;
- uuid << "Cluster for process with id: " << pid;
- return uuid;
- }
-}
-
-namespace NActors {
- ui64 TScheduledEventQueueItem::NextUniqueId = 0;
-
- void PrintEvent(TAutoPtr<IEventHandle>& ev, const TTestActorRuntimeBase* runtime) {
- Cerr << "mailbox: " << ev->GetRecipientRewrite().Hint() << ", type: " << Sprintf("%08x", ev->GetTypeRewrite())
- << ", from " << ev->Sender.LocalId();
- TString name = runtime->GetActorName(ev->Sender);
- if (!name.empty())
- Cerr << " \"" << name << "\"";
- Cerr << ", to " << ev->GetRecipientRewrite().LocalId();
- name = runtime->GetActorName(ev->GetRecipientRewrite());
- if (!name.empty())
- Cerr << " \"" << name << "\"";
- Cerr << ", ";
- if (ev->HasEvent())
- Cerr << " : " << (PRINT_EVENT_BODY ? ev->ToString() : ev->GetTypeName());
- else if (ev->HasBuffer())
- Cerr << " : BUFFER";
- else
- Cerr << " : EMPTY";
-
- Cerr << "\n";
- }
-
- TTestActorRuntimeBase::TNodeDataBase::TNodeDataBase() {
- ActorSystemTimestamp = nullptr;
- ActorSystemMonotonic = nullptr;
- }
-
- void TTestActorRuntimeBase::TNodeDataBase::Stop() {
- if (Poller)
- Poller->Stop();
-
- if (MailboxTable) {
- for (ui32 round = 0; !MailboxTable->Cleanup(); ++round)
- Y_ABORT_UNLESS(round < 10, "cyclic event/actor spawn while trying to shutdown actorsystem stub");
- }
-
- if (ActorSystem)
- ActorSystem->Stop();
-
- ActorSystem.Destroy();
- Poller.Reset();
- }
-
- TTestActorRuntimeBase::TNodeDataBase::~TNodeDataBase() {
- Stop();
- }
-
-
- class TTestActorRuntimeBase::TEdgeActor : public TActor<TEdgeActor> {
- public:
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::TEST_ACTOR_RUNTIME;
- }
-
- TEdgeActor(TTestActorRuntimeBase* runtime)
- : TActor(&TEdgeActor::StateFunc)
- , Runtime(runtime)
- {
- }
-
- STFUNC(StateFunc) {
- TGuard<TMutex> guard(Runtime->Mutex);
- bool verbose = (Runtime->CurrentDispatchContext ? !Runtime->CurrentDispatchContext->Options->Quiet : true) && VERBOSE;
- if (Runtime->BlockedOutput.find(ev->Sender) != Runtime->BlockedOutput.end()) {
- verbose = false;
- }
-
- if (verbose) {
- Cerr << "Got event at " << TInstant::MicroSeconds(Runtime->CurrentTimestamp) << ", ";
- PrintEvent(ev, Runtime);
- }
-
- if (!Runtime->EventFilterFunc(*Runtime, ev)) {
- ui32 nodeId = ev->GetRecipientRewrite().NodeId();
- Y_ABORT_UNLESS(nodeId != 0);
- ui32 mailboxHint = ev->GetRecipientRewrite().Hint();
- Runtime->GetMailbox(nodeId, mailboxHint).Send(ev);
- Runtime->MailboxesHasEvents.Signal();
- if (verbose)
- Cerr << "Event was added to sent queue\n";
- }
- else {
- if (verbose)
- Cerr << "Event was dropped\n";
- }
- }
-
- private:
- TTestActorRuntimeBase* Runtime;
- };
-
- void TEventMailBox::Send(TAutoPtr<IEventHandle> ev) {
- IEventHandle* ptr = ev.Get();
- Y_ABORT_UNLESS(ptr);
-#ifdef DEBUG_ORDER_EVENTS
- ui64 counter = NextToSend++;
- TrackSent[ptr] = counter;
-#endif
- Sent.push_back(ev);
- }
-
- TAutoPtr<IEventHandle> TEventMailBox::Pop() {
- TAutoPtr<IEventHandle> result = Sent.front();
- Sent.pop_front();
-#ifdef DEBUG_ORDER_EVENTS
- auto it = TrackSent.find(result.Get());
- if (it != TrackSent.end()) {
- Y_ABORT_UNLESS(ExpectedReceive == it->second);
- TrackSent.erase(result.Get());
- ++ExpectedReceive;
- }
-#endif
- return result;
- }
-
- bool TEventMailBox::IsEmpty() const {
- return Sent.empty();
- }
-
- void TEventMailBox::Capture(TEventsList& evList) {
- evList.insert(evList.end(), Sent.begin(), Sent.end());
- Sent.clear();
- }
-
- void TEventMailBox::PushFront(TAutoPtr<IEventHandle>& ev) {
- Sent.push_front(ev);
- }
-
- void TEventMailBox::PushFront(TEventsList& evList) {
- for (auto rit = evList.rbegin(); rit != evList.rend(); ++rit) {
- if (*rit) {
- Sent.push_front(*rit);
- }
- }
- }
-
- void TEventMailBox::CaptureScheduled(TScheduledEventsList& evList) {
- for (auto it = Scheduled.begin(); it != Scheduled.end(); ++it) {
- evList.insert(*it);
- }
-
- Scheduled.clear();
- }
-
- void TEventMailBox::PushScheduled(TScheduledEventsList& evList) {
- for (auto it = evList.begin(); it != evList.end(); ++it) {
- if (it->Event) {
- Scheduled.insert(*it);
- }
- }
-
- evList.clear();
- }
-
- bool TEventMailBox::IsActive(const TInstant& currentTime) const {
- return currentTime >= InactiveUntil;
- }
-
- void TEventMailBox::Freeze(const TInstant& deadline) {
- if (deadline > InactiveUntil)
- InactiveUntil = deadline;
- }
-
- TInstant TEventMailBox::GetInactiveUntil() const {
- return InactiveUntil;
- }
-
- void TEventMailBox::Schedule(const TScheduledEventQueueItem& item) {
- Scheduled.insert(item);
- }
-
- bool TEventMailBox::IsScheduledEmpty() const {
- return Scheduled.empty();
- }
-
- TInstant TEventMailBox::GetFirstScheduleDeadline() const {
- return Scheduled.begin()->Deadline;
- }
-
- ui64 TEventMailBox::GetSentEventCount() const {
- return Sent.size();
- }
-
- class TTestActorRuntimeBase::TTimeProvider : public ITimeProvider {
- public:
- TTimeProvider(TTestActorRuntimeBase& runtime)
- : Runtime(runtime)
- {
- }
-
- TInstant Now() override {
- return Runtime.GetCurrentTime();
- }
-
- private:
- TTestActorRuntimeBase& Runtime;
- };
-
- class TTestActorRuntimeBase::TMonotonicTimeProvider : public IMonotonicTimeProvider {
- public:
- TMonotonicTimeProvider(TTestActorRuntimeBase& runtime)
- : Runtime(runtime)
- { }
-
- TMonotonic Now() override {
- return Runtime.GetCurrentMonotonicTime();
- }
-
- private:
- TTestActorRuntimeBase& Runtime;
- };
-
- class TTestActorRuntimeBase::TSchedulerThreadStub : public ISchedulerThread {
- public:
- TSchedulerThreadStub(TTestActorRuntimeBase* runtime, TTestActorRuntimeBase::TNodeDataBase* node)
- : Runtime(runtime)
- , Node(node)
- {
- Y_UNUSED(Runtime);
- }
-
- void Prepare(TActorSystem *actorSystem, volatile ui64 *currentTimestamp, volatile ui64 *currentMonotonic) override {
- Y_UNUSED(actorSystem);
- Node->ActorSystemTimestamp = currentTimestamp;
- Node->ActorSystemMonotonic = currentMonotonic;
- }
-
- void PrepareSchedules(NSchedulerQueue::TReader **readers, ui32 scheduleReadersCount) override {
- Y_UNUSED(readers);
- Y_UNUSED(scheduleReadersCount);
- }
-
- void Start() override {
- }
-
- void PrepareStop() override {
- }
-
- void Stop() override {
- }
-
- private:
- TTestActorRuntimeBase* Runtime;
- TTestActorRuntimeBase::TNodeDataBase* Node;
- };
-
- class TTestActorRuntimeBase::TExecutorPoolStub : public IExecutorPool {
- public:
- TExecutorPoolStub(TTestActorRuntimeBase* runtime, ui32 nodeIndex, TTestActorRuntimeBase::TNodeDataBase* node, ui32 poolId)
- : IExecutorPool(poolId)
- , Runtime(runtime)
- , NodeIndex(nodeIndex)
- , Node(node)
- {
- }
-
- TTestActorRuntimeBase* GetRuntime() {
- return Runtime;
- }
-
- // for threads
- ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) override {
- Y_UNUSED(wctx);
- Y_UNUSED(revolvingCounter);
- Y_ABORT();
- }
-
- void ReclaimMailbox(TMailboxType::EType mailboxType, ui32 hint, TWorkerId workerId, ui64 revolvingCounter) override {
- Y_UNUSED(workerId);
- Node->MailboxTable->ReclaimMailbox(mailboxType, hint, revolvingCounter);
- }
-
- TMailboxHeader *ResolveMailbox(ui32 hint) override {
- return Node->MailboxTable->Get(hint);
- }
-
- void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, TWorkerId workerId) override {
- DoSchedule(deadline, ev, cookie, workerId);
- }
-
- void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, TWorkerId workerId) override {
- DoSchedule(TInstant::FromValue(deadline.GetValue()), ev, cookie, workerId);
- }
-
- void Schedule(TDuration delay, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, TWorkerId workerId) override {
- TInstant deadline = Runtime->GetTimeProvider()->Now() + delay;
- DoSchedule(deadline, ev, cookie, workerId);
- }
-
- void DoSchedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, TWorkerId workerId) {
- Y_UNUSED(workerId);
-
- TGuard<TMutex> guard(Runtime->Mutex);
- bool verbose = (Runtime->CurrentDispatchContext ? !Runtime->CurrentDispatchContext->Options->Quiet : true) && VERBOSE;
- if (Runtime->BlockedOutput.find(ev->Sender) != Runtime->BlockedOutput.end()) {
- verbose = false;
- }
-
- if (verbose) {
- Cerr << "Got scheduled event at " << TInstant::MicroSeconds(Runtime->CurrentTimestamp) << ", ";
- PrintEvent(ev, Runtime);
- }
-
- auto now = Runtime->GetTimeProvider()->Now();
- if (deadline < now) {
- deadline = now; // avoid going backwards in time
- }
- TDuration delay = (deadline - now);
-
- if (Runtime->SingleSysEnv || !Runtime->ScheduledEventFilterFunc(*Runtime, ev, delay, deadline)) {
- ui32 mailboxHint = ev->GetRecipientRewrite().Hint();
- Runtime->GetMailbox(Runtime->FirstNodeId + NodeIndex, mailboxHint).Schedule(TScheduledEventQueueItem(deadline, ev, cookie));
- Runtime->MailboxesHasEvents.Signal();
- if (verbose)
- Cerr << "Event was added to scheduled queue\n";
- } else {
- if (cookie) {
- cookie->Detach();
- }
- if (verbose) {
- Cerr << "Scheduled event for " << ev->GetRecipientRewrite().ToString() << " was dropped\n";
- }
- }
- }
-
- // for actorsystem
- bool SpecificSend(TAutoPtr<IEventHandle>& ev) override {
- return Send(ev);
- }
-
- bool Send(TAutoPtr<IEventHandle>& ev) override {
- TGuard<TMutex> guard(Runtime->Mutex);
- bool verbose = (Runtime->CurrentDispatchContext ? !Runtime->CurrentDispatchContext->Options->Quiet : true) && VERBOSE;
- if (Runtime->BlockedOutput.find(ev->Sender) != Runtime->BlockedOutput.end()) {
- verbose = false;
- }
-
- if (verbose) {
- Cerr << "Got event at " << TInstant::MicroSeconds(Runtime->CurrentTimestamp) << ", ";
- PrintEvent(ev, Runtime);
- }
-
- if (!Runtime->EventFilterFunc(*Runtime, ev)) {
- ui32 nodeId = ev->GetRecipientRewrite().NodeId();
- Y_ABORT_UNLESS(nodeId != 0);
- TNodeDataBase* node = Runtime->Nodes[nodeId].Get();
-
- if (!AllowSendFrom(node, ev)) {
- return true;
- }
-
- ui32 mailboxHint = ev->GetRecipientRewrite().Hint();
- if (ev->GetTypeRewrite() == ui32(NActors::NLog::EEv::Log)) {
- const NActors::TActorId loggerActorId = NActors::TActorId(nodeId, "logger");
- TActorId logger = node->ActorSystem->LookupLocalService(loggerActorId);
- if (ev->GetRecipientRewrite() == logger) {
- TMailboxHeader* mailbox = node->MailboxTable->Get(mailboxHint);
- IActor* recipientActor = mailbox->FindActor(ev->GetRecipientRewrite().LocalId());
- if (recipientActor) {
- TActorContext ctx(*mailbox, *node->ExecutorThread, GetCycleCountFast(), ev->GetRecipientRewrite());
- TActivationContext *prevTlsActivationContext = TlsActivationContext;
- TlsActivationContext = &ctx;
- recipientActor->Receive(ev);
- TlsActivationContext = prevTlsActivationContext;
- // we expect the logger to never die in tests
- }
- }
- } else {
- Runtime->GetMailbox(nodeId, mailboxHint).Send(ev);
- Runtime->MailboxesHasEvents.Signal();
- }
- if (verbose)
- Cerr << "Event was added to sent queue\n";
- } else {
- if (verbose)
- Cerr << "Event was dropped\n";
- }
- return true;
- }
-
- void ScheduleActivation(ui32 activation) override {
- Y_UNUSED(activation);
- }
-
- void SpecificScheduleActivation(ui32 activation) override {
- Y_UNUSED(activation);
- }
-
- void ScheduleActivationEx(ui32 activation, ui64 revolvingCounter) override {
- Y_UNUSED(activation);
- Y_UNUSED(revolvingCounter);
- }
-
- TActorId Register(IActor *actor, TMailboxType::EType mailboxType, ui64 revolvingCounter,
- const TActorId& parentId) override {
- return Runtime->Register(actor, NodeIndex, PoolId, mailboxType, revolvingCounter, parentId);
- }
-
- TActorId Register(IActor *actor, TMailboxHeader *mailbox, ui32 hint, const TActorId& parentId) override {
- return Runtime->Register(actor, NodeIndex, PoolId, mailbox, hint, parentId);
- }
-
- // lifecycle stuff
- void Prepare(TActorSystem *actorSystem, NSchedulerQueue::TReader **scheduleReaders, ui32 *scheduleSz) override {
- Y_UNUSED(actorSystem);
- Y_UNUSED(scheduleReaders);
- Y_UNUSED(scheduleSz);
- }
-
- void Start() override {
- }
-
- void PrepareStop() override {
- }
-
- void Shutdown() override {
- }
-
- bool Cleanup() override {
- return true;
- }
-
- // generic
- TAffinity* Affinity() const override {
- Y_ABORT();
- }
-
- private:
- TTestActorRuntimeBase* const Runtime;
- const ui32 NodeIndex;
- TTestActorRuntimeBase::TNodeDataBase* const Node;
- };
-
- IExecutorPool* TTestActorRuntimeBase::CreateExecutorPoolStub(TTestActorRuntimeBase* runtime, ui32 nodeIndex, TTestActorRuntimeBase::TNodeDataBase* node, ui32 poolId) {
- return new TExecutorPoolStub{runtime, nodeIndex, node, poolId};
- }
-
-
- ui32 TTestActorRuntimeBase::NextNodeId = 1;
-
- TTestActorRuntimeBase::TTestActorRuntimeBase(THeSingleSystemEnv)
- : TTestActorRuntimeBase(1, 1, false)
- {
- SingleSysEnv = true;
- }
-
- TTestActorRuntimeBase::TTestActorRuntimeBase(ui32 nodeCount, ui32 dataCenterCount, bool useRealThreads)
- : ScheduledCount(0)
- , ScheduledLimit(100000)
- , MainThreadId(TThread::CurrentThreadId())
- , ClusterUUID(MakeClusterId())
- , FirstNodeId(NextNodeId)
- , NodeCount(nodeCount)
- , DataCenterCount(dataCenterCount)
- , UseRealThreads(useRealThreads)
- , LocalId(0)
- , DispatchCyclesCount(0)
- , DispatchedEventsCount(0)
- , NeedMonitoring(false)
- , RandomProvider(CreateDeterministicRandomProvider(DefaultRandomSeed))
- , TimeProvider(new TTimeProvider(*this))
- , MonotonicTimeProvider(new TMonotonicTimeProvider(*this))
- , ShouldContinue()
- , CurrentTimestamp(0)
- , DispatchTimeout(DEFAULT_DISPATCH_TIMEOUT)
- , ReschedulingDelay(TDuration::MicroSeconds(0))
- , ObserverFunc(&TTestActorRuntimeBase::DefaultObserverFunc)
- , ScheduledEventsSelectorFunc(&CollapsedTimeScheduledEventsSelector)
- , EventFilterFunc(&TTestActorRuntimeBase::DefaultFilterFunc)
- , ScheduledEventFilterFunc(&TTestActorRuntimeBase::NopFilterFunc)
- , RegistrationObserver(&TTestActorRuntimeBase::DefaultRegistrationObserver)
- , CurrentDispatchContext(nullptr)
- {
- SetDispatcherRandomSeed(TInstant::Now(), 0);
- EnableActorCallstack();
- }
-
- void TTestActorRuntimeBase::InitNode(TNodeDataBase* node, size_t nodeIndex) {
- const NActors::TActorId loggerActorId = NActors::TActorId(FirstNodeId + nodeIndex, "logger");
- node->LogSettings = new NActors::NLog::TSettings(loggerActorId, NActorsServices::LOGGER,
- NActors::NLog::PRI_WARN, NActors::NLog::PRI_WARN, 0);
- node->LogSettings->SetAllowDrop(false);
- node->LogSettings->SetThrottleDelay(TDuration::Zero());
- node->DynamicCounters = new NMonitoring::TDynamicCounters;
-
- InitNodeImpl(node, nodeIndex);
- }
-
- void TTestActorRuntimeBase::InitNodeImpl(TNodeDataBase* node, size_t nodeIndex) {
- node->LogSettings->Append(
- NActorsServices::EServiceCommon_MIN,
- NActorsServices::EServiceCommon_MAX,
- NActorsServices::EServiceCommon_Name
- );
-
- if (!UseRealThreads) {
- node->SchedulerPool.Reset(CreateExecutorPoolStub(this, nodeIndex, node, 0));
- node->MailboxTable.Reset(new TMailboxTable());
- node->ActorSystem = MakeActorSystem(nodeIndex, node);
- node->ExecutorThread.Reset(new TExecutorThread(0, 0, node->ActorSystem.Get(), node->SchedulerPool.Get(), node->MailboxTable.Get(), "TestExecutor"));
- } else {
- node->ActorSystem = MakeActorSystem(nodeIndex, node);
- }
-
- node->ActorSystem->Start();
- }
-
- bool TTestActorRuntimeBase::AllowSendFrom(TNodeDataBase* node, TAutoPtr<IEventHandle>& ev) {
- ui64 senderLocalId = ev->Sender.LocalId();
- ui64 senderMailboxHint = ev->Sender.Hint();
- TMailboxHeader* senderMailbox = node->MailboxTable->Get(senderMailboxHint);
- if (senderMailbox) {
- IActor* senderActor = senderMailbox->FindActor(senderLocalId);
- TTestDecorator *decorator = dynamic_cast<TTestDecorator*>(senderActor);
- return !decorator || decorator->BeforeSending(ev);
- }
- return true;
- }
-
- TTestActorRuntimeBase::TTestActorRuntimeBase(ui32 nodeCount, ui32 dataCenterCount)
- : TTestActorRuntimeBase(nodeCount, dataCenterCount, false) {
- }
-
- TTestActorRuntimeBase::TTestActorRuntimeBase(ui32 nodeCount, bool useRealThreads)
- : TTestActorRuntimeBase(nodeCount, nodeCount, useRealThreads) {
- }
-
- TTestActorRuntimeBase::~TTestActorRuntimeBase() {
- CleanupNodes();
- Cerr.Flush();
- Cerr.Flush();
- Clog.Flush();
-
- DisableActorCallstack();
- }
-
- void TTestActorRuntimeBase::CleanupNodes() {
- Nodes.clear();
- }
-
- bool TTestActorRuntimeBase::IsRealThreads() const {
- return UseRealThreads;
- }
-
- TTestActorRuntimeBase::EEventAction TTestActorRuntimeBase::DefaultObserverFunc(TAutoPtr<IEventHandle>& event) {
- Y_UNUSED(event);
- return EEventAction::PROCESS;
- }
-
- void TTestActorRuntimeBase::DroppingScheduledEventsSelector(TTestActorRuntimeBase& runtime, TScheduledEventsList& scheduledEvents, TEventsList& queue) {
- Y_UNUSED(runtime);
- Y_UNUSED(queue);
- scheduledEvents.clear();
- }
-
- bool TTestActorRuntimeBase::DefaultFilterFunc(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
- Y_UNUSED(runtime);
- Y_UNUSED(event);
- return false;
- }
-
- bool TTestActorRuntimeBase::NopFilterFunc(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event, TDuration delay, TInstant& deadline) {
- Y_UNUSED(runtime);
- Y_UNUSED(delay);
- Y_UNUSED(event);
- Y_UNUSED(deadline);
- return true;
- }
-
-
- void TTestActorRuntimeBase::DefaultRegistrationObserver(TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId) {
- if (runtime.ScheduleWhiteList.find(parentId) != runtime.ScheduleWhiteList.end()) {
- runtime.ScheduleWhiteList.insert(actorId);
- runtime.ScheduleWhiteListParent[actorId] = parentId;
- }
- }
-
- class TScheduledTreeItem {
- public:
- TString Name;
- ui64 Count;
- TVector<TScheduledTreeItem> Children;
-
- TScheduledTreeItem(const TString& name)
- : Name(name)
- , Count(0)
- {}
-
- TScheduledTreeItem* GetItem(const TString& name) {
- TScheduledTreeItem* item = nullptr;
- for (TScheduledTreeItem& i : Children) {
- if (i.Name == name) {
- item = &i;
- break;
- }
- }
- if (item != nullptr)
- return item;
- Children.emplace_back(name);
- return &Children.back();
- }
-
- void RecursiveSort() {
- Sort(Children, [](const TScheduledTreeItem& a, const TScheduledTreeItem& b) -> bool { return a.Count > b.Count; });
- for (TScheduledTreeItem& item : Children) {
- item.RecursiveSort();
- }
- }
-
- void Print(IOutputStream& stream, const TString& prefix) {
- for (auto it = Children.begin(); it != Children.end(); ++it) {
- bool lastChild = (std::next(it) == Children.end());
- TString connectionPrefix = lastChild ? "└─ " : "├─ ";
- TString subChildPrefix = lastChild ? " " : "│ ";
- stream << prefix << connectionPrefix << it->Name << " (" << it->Count << ")\n";
- it->Print(stream, prefix + subChildPrefix);
- }
- }
-
- void Print(IOutputStream& stream) {
- stream << Name << " (" << Count << ")\n";
- Print(stream, TString());
- }
- };
-
- void TTestActorRuntimeBase::CollapsedTimeScheduledEventsSelector(TTestActorRuntimeBase& runtime, TScheduledEventsList& scheduledEvents, TEventsList& queue) {
- if (scheduledEvents.empty())
- return;
-
- TInstant time = scheduledEvents.begin()->Deadline;
- while (!scheduledEvents.empty() && scheduledEvents.begin()->Deadline == time) {
-// static THashMap<std::pair<TActorId, TString>, ui64> eventTypes;
- auto& item = *scheduledEvents.begin();
- TString name = item.Event->GetTypeName();
-// eventTypes[std::make_pair(item.Event->Recipient, name)]++;
- runtime.ScheduledCount++;
- if (runtime.ScheduledCount > runtime.ScheduledLimit) {
-// TScheduledTreeItem root("Root");
-// TVector<TString> path;
-// for (const auto& pr : eventTypes) {
-// path.clear();
-// path.push_back(runtime.GetActorName(pr.first.first));
-// for (auto it = runtime.ScheduleWhiteListParent.find(pr.first.first); it != runtime.ScheduleWhiteListParent.end(); it = runtime.ScheduleWhiteListParent.find(it->second)) {
-// path.insert(path.begin(), runtime.GetActorName(it->second));
-// }
-// path.push_back("<" + pr.first.second + ">"); // event name;
-// ui64 count = pr.second;
-// TScheduledTreeItem* item = &root;
-// item->Count += count;
-// for (TString name : path) {
-// item = item->GetItem(name);
-// item->Count += count;
-// }
-// }
-// root.RecursiveSort();
-// root.Print(Cerr);
-
- ythrow TSchedulingLimitReachedException(runtime.ScheduledLimit);
- }
- if (item.Cookie->Get()) {
- if (item.Cookie->Detach()) {
- queue.push_back(item.Event);
- }
- } else {
- queue.push_back(item.Event);
- }
-
- scheduledEvents.erase(scheduledEvents.begin());
- }
-
- runtime.UpdateCurrentTime(time);
- }
-
- TTestActorRuntimeBase::TEventObserver TTestActorRuntimeBase::SetObserverFunc(TEventObserver observerFunc) {
- TGuard<TMutex> guard(Mutex);
- auto result = ObserverFunc;
- ObserverFunc = observerFunc;
- return result;
- }
-
- TTestActorRuntimeBase::TScheduledEventsSelector TTestActorRuntimeBase::SetScheduledEventsSelectorFunc(TScheduledEventsSelector scheduledEventsSelectorFunc) {
- TGuard<TMutex> guard(Mutex);
- auto result = ScheduledEventsSelectorFunc;
- ScheduledEventsSelectorFunc = scheduledEventsSelectorFunc;
- return result;
- }
-
- TTestActorRuntimeBase::TEventFilter TTestActorRuntimeBase::SetEventFilter(TEventFilter filterFunc) {
- TGuard<TMutex> guard(Mutex);
- auto result = EventFilterFunc;
- EventFilterFunc = filterFunc;
- return result;
- }
-
- TTestActorRuntimeBase::TScheduledEventFilter TTestActorRuntimeBase::SetScheduledEventFilter(TScheduledEventFilter filterFunc) {
- TGuard<TMutex> guard(Mutex);
- auto result = ScheduledEventFilterFunc;
- ScheduledEventFilterFunc = filterFunc;
- return result;
- }
-
- TTestActorRuntimeBase::TRegistrationObserver TTestActorRuntimeBase::SetRegistrationObserverFunc(TRegistrationObserver observerFunc) {
- TGuard<TMutex> guard(Mutex);
- auto result = RegistrationObserver;
- RegistrationObserver = observerFunc;
- return result;
- }
-
- bool TTestActorRuntimeBase::IsVerbose() {
- return VERBOSE;
- }
-
- void TTestActorRuntimeBase::SetVerbose(bool verbose) {
- VERBOSE = verbose;
- }
-
- void TTestActorRuntimeBase::AddLocalService(const TActorId& actorId, TActorSetupCmd cmd, ui32 nodeIndex) {
- Y_ABORT_UNLESS(!IsInitialized);
- Y_ABORT_UNLESS(nodeIndex < NodeCount);
- auto node = Nodes[nodeIndex + FirstNodeId];
- if (!node) {
- node = GetNodeFactory().CreateNode();
- Nodes[nodeIndex + FirstNodeId] = node;
- }
-
- node->LocalServicesActors[actorId] = cmd.Actor.get();
- node->LocalServices.push_back(std::make_pair(actorId, TTestActorSetupCmd(std::move(cmd))));
- }
-
- void TTestActorRuntimeBase::InitNodes() {
- NextNodeId += NodeCount;
- Y_ABORT_UNLESS(NodeCount > 0);
-
- for (ui32 nodeIndex = 0; nodeIndex < NodeCount; ++nodeIndex) {
- auto nodeIt = Nodes.emplace(FirstNodeId + nodeIndex, GetNodeFactory().CreateNode()).first;
- TNodeDataBase* node = nodeIt->second.Get();
- InitNode(node, nodeIndex);
- }
-
- }
-
- void TTestActorRuntimeBase::Initialize() {
- InitNodes();
- IsInitialized = true;
- }
-
- void SetupCrossDC() {
-
- }
-
- TDuration TTestActorRuntimeBase::SetDispatchTimeout(TDuration timeout) {
- TGuard<TMutex> guard(Mutex);
- TDuration oldTimeout = DispatchTimeout;
- DispatchTimeout = timeout;
- return oldTimeout;
- }
-
- TDuration TTestActorRuntimeBase::SetReschedulingDelay(TDuration delay) {
- TGuard<TMutex> guard(Mutex);
- TDuration oldDelay = ReschedulingDelay;
- ReschedulingDelay = delay;
- return oldDelay;
- }
-
- void TTestActorRuntimeBase::SetLogBackend(const TAutoPtr<TLogBackend> logBackend) {
- Y_ABORT_UNLESS(!IsInitialized);
- TGuard<TMutex> guard(Mutex);
- LogBackend = logBackend;
- }
-
- void TTestActorRuntimeBase::SetLogPriority(NActors::NLog::EComponent component, NActors::NLog::EPriority priority) {
- TGuard<TMutex> guard(Mutex);
- for (ui32 nodeIndex = 0; nodeIndex < NodeCount; ++nodeIndex) {
- TNodeDataBase* node = Nodes[FirstNodeId + nodeIndex].Get();
- TString explanation;
- auto status = node->LogSettings->SetLevel(priority, component, explanation);
- if (status) {
- Y_ABORT("SetLogPriority failed: %s", explanation.c_str());
- }
- }
- }
-
- TInstant TTestActorRuntimeBase::GetCurrentTime() const {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(!UseRealThreads);
- return TInstant::MicroSeconds(CurrentTimestamp);
- }
-
- TMonotonic TTestActorRuntimeBase::GetCurrentMonotonicTime() const {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(!UseRealThreads);
- return TMonotonic::MicroSeconds(CurrentTimestamp);
- }
-
- void TTestActorRuntimeBase::UpdateCurrentTime(TInstant newTime) {
- static int counter = 0;
- ++counter;
- if (VERBOSE) {
- Cerr << "UpdateCurrentTime(" << counter << "," << newTime << ")\n";
- }
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(!UseRealThreads);
- if (newTime.MicroSeconds() > CurrentTimestamp) {
- CurrentTimestamp = newTime.MicroSeconds();
- for (auto& kv : Nodes) {
- AtomicStore(kv.second->ActorSystemTimestamp, CurrentTimestamp);
- AtomicStore(kv.second->ActorSystemMonotonic, CurrentTimestamp);
- }
- }
- }
-
- void TTestActorRuntimeBase::AdvanceCurrentTime(TDuration duration) {
- UpdateCurrentTime(GetCurrentTime() + duration);
- }
-
- TIntrusivePtr<ITimeProvider> TTestActorRuntimeBase::GetTimeProvider() {
- Y_ABORT_UNLESS(!UseRealThreads);
- return TimeProvider;
- }
-
- TIntrusivePtr<IMonotonicTimeProvider> TTestActorRuntimeBase::GetMonotonicTimeProvider() {
- Y_ABORT_UNLESS(!UseRealThreads);
- return MonotonicTimeProvider;
- }
-
- ui32 TTestActorRuntimeBase::GetNodeId(ui32 index) const {
- Y_ABORT_UNLESS(index < NodeCount);
- return FirstNodeId + index;
- }
-
- ui32 TTestActorRuntimeBase::GetNodeCount() const {
- return NodeCount;
- }
-
- ui64 TTestActorRuntimeBase::AllocateLocalId() {
- TGuard<TMutex> guard(Mutex);
- ui64 nextId = ++LocalId;
- if (VERBOSE) {
- Cerr << "Allocated id: " << nextId << "\n";
- }
-
- return nextId;
- }
-
- ui32 TTestActorRuntimeBase::InterconnectPoolId() const {
- if (UseRealThreads && NSan::TSanIsOn()) {
- // Interconnect coroutines may move across threads
- // Use a special single-threaded pool to avoid that
- return 4;
- }
- return 0;
- }
-
- TString TTestActorRuntimeBase::GetTempDir() {
- if (!TmpDir)
- TmpDir.Reset(new TTempDir());
- return (*TmpDir)();
- }
-
- TActorId TTestActorRuntimeBase::Register(IActor* actor, ui32 nodeIndex, ui32 poolId, TMailboxType::EType mailboxType,
- ui64 revolvingCounter, const TActorId& parentId) {
- Y_ABORT_UNLESS(nodeIndex < NodeCount);
- TGuard<TMutex> guard(Mutex);
- TNodeDataBase* node = Nodes[FirstNodeId + nodeIndex].Get();
- if (UseRealThreads) {
- Y_ABORT_UNLESS(poolId < node->ExecutorPools.size());
- return node->ExecutorPools[poolId]->Register(actor, mailboxType, revolvingCounter, parentId);
- }
-
- // first step - find good enough mailbox
- ui32 hint = 0;
- TMailboxHeader *mailbox = nullptr;
-
- {
- ui32 hintBackoff = 0;
-
- while (hint == 0) {
- hint = node->MailboxTable->AllocateMailbox(mailboxType, ++revolvingCounter);
- mailbox = node->MailboxTable->Get(hint);
-
- if (!mailbox->LockFromFree()) {
- node->MailboxTable->ReclaimMailbox(mailboxType, hintBackoff, ++revolvingCounter);
- hintBackoff = hint;
- hint = 0;
- }
- }
-
- node->MailboxTable->ReclaimMailbox(mailboxType, hintBackoff, ++revolvingCounter);
- }
-
- const ui64 localActorId = AllocateLocalId();
- if (VERBOSE) {
- Cerr << "Register actor " << TypeName(*actor) << " as " << localActorId << ", mailbox: " << hint << "\n";
- }
-
- // ok, got mailbox
- mailbox->AttachActor(localActorId, actor);
-
- // do init
- const TActorId actorId(FirstNodeId + nodeIndex, poolId, localActorId, hint);
- ActorNames[actorId] = TypeName(*actor);
- RegistrationObserver(*this, parentId ? parentId : CurrentRecipient, actorId);
- DoActorInit(node->ActorSystem.Get(), actor, actorId, parentId ? parentId : CurrentRecipient);
-
- switch (mailboxType) {
- case TMailboxType::Simple:
- UnlockFromExecution((TMailboxTable::TSimpleMailbox *)mailbox, node->ExecutorPools[0], false, hint, MaxWorkers, ++revolvingCounter);
- break;
- case TMailboxType::Revolving:
- UnlockFromExecution((TMailboxTable::TRevolvingMailbox *)mailbox, node->ExecutorPools[0], false, hint, MaxWorkers, ++revolvingCounter);
- break;
- case TMailboxType::HTSwap:
- UnlockFromExecution((TMailboxTable::THTSwapMailbox *)mailbox, node->ExecutorPools[0], false, hint, MaxWorkers, ++revolvingCounter);
- break;
- case TMailboxType::ReadAsFilled:
- UnlockFromExecution((TMailboxTable::TReadAsFilledMailbox *)mailbox, node->ExecutorPools[0], false, hint, MaxWorkers, ++revolvingCounter);
- break;
- case TMailboxType::TinyReadAsFilled:
- UnlockFromExecution((TMailboxTable::TTinyReadAsFilledMailbox *)mailbox, node->ExecutorPools[0], false, hint, MaxWorkers, ++revolvingCounter);
- break;
- default:
- Y_ABORT("Unsupported mailbox type");
- }
-
- return actorId;
- }
-
- TActorId TTestActorRuntimeBase::Register(IActor *actor, ui32 nodeIndex, ui32 poolId, TMailboxHeader *mailbox, ui32 hint,
- const TActorId& parentId) {
- Y_ABORT_UNLESS(nodeIndex < NodeCount);
- TGuard<TMutex> guard(Mutex);
- TNodeDataBase* node = Nodes[FirstNodeId + nodeIndex].Get();
- if (UseRealThreads) {
- Y_ABORT_UNLESS(poolId < node->ExecutorPools.size());
- return node->ExecutorPools[poolId]->Register(actor, mailbox, hint, parentId);
- }
-
- const ui64 localActorId = AllocateLocalId();
- if (VERBOSE) {
- Cerr << "Register actor " << TypeName(*actor) << " as " << localActorId << "\n";
- }
-
- mailbox->AttachActor(localActorId, actor);
- const TActorId actorId(FirstNodeId + nodeIndex, poolId, localActorId, hint);
- ActorNames[actorId] = TypeName(*actor);
- RegistrationObserver(*this, parentId ? parentId : CurrentRecipient, actorId);
- DoActorInit(node->ActorSystem.Get(), actor, actorId, parentId ? parentId : CurrentRecipient);
-
- return actorId;
- }
-
- TActorId TTestActorRuntimeBase::RegisterService(const TActorId& serviceId, const TActorId& actorId, ui32 nodeIndex) {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(nodeIndex < NodeCount);
- TNodeDataBase* node = Nodes[FirstNodeId + nodeIndex].Get();
- if (!UseRealThreads) {
- IActor* actor = FindActor(actorId, node);
- node->LocalServicesActors[serviceId] = actor;
- node->ActorToActorId[actor] = actorId;
- }
-
- return node->ActorSystem->RegisterLocalService(serviceId, actorId);
- }
-
- TActorId TTestActorRuntimeBase::AllocateEdgeActor(ui32 nodeIndex) {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(nodeIndex < NodeCount);
- TActorId edgeActor = Register(new TEdgeActor(this), nodeIndex);
- EdgeActors.insert(edgeActor);
- EdgeActorByMailbox[TEventMailboxId(edgeActor.NodeId(), edgeActor.Hint())] = edgeActor;
- return edgeActor;
- }
-
- TEventsList TTestActorRuntimeBase::CaptureEvents() {
- TGuard<TMutex> guard(Mutex);
- TEventsList result;
- for (auto& mbox : Mailboxes) {
- mbox.second->Capture(result);
- }
-
- return result;
- }
-
- TEventsList TTestActorRuntimeBase::CaptureMailboxEvents(ui32 hint, ui32 nodeId) {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(nodeId >= FirstNodeId && nodeId < FirstNodeId + NodeCount);
- TEventsList result;
- GetMailbox(nodeId, hint).Capture(result);
- return result;
- }
-
- void TTestActorRuntimeBase::PushFront(TAutoPtr<IEventHandle>& ev) {
- TGuard<TMutex> guard(Mutex);
- ui32 nodeId = ev->GetRecipientRewrite().NodeId();
- Y_ABORT_UNLESS(nodeId != 0);
- GetMailbox(nodeId, ev->GetRecipientRewrite().Hint()).PushFront(ev);
- }
-
- void TTestActorRuntimeBase::PushEventsFront(TEventsList& events) {
- TGuard<TMutex> guard(Mutex);
- for (auto rit = events.rbegin(); rit != events.rend(); ++rit) {
- if (*rit) {
- auto& ev = *rit;
- ui32 nodeId = ev->GetRecipientRewrite().NodeId();
- Y_ABORT_UNLESS(nodeId != 0);
- GetMailbox(nodeId, ev->GetRecipientRewrite().Hint()).PushFront(ev);
- }
- }
-
- events.clear();
- }
-
- void TTestActorRuntimeBase::PushMailboxEventsFront(ui32 hint, ui32 nodeId, TEventsList& events) {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(nodeId >= FirstNodeId && nodeId < FirstNodeId + NodeCount);
- TEventsList result;
- GetMailbox(nodeId, hint).PushFront(events);
- events.clear();
- }
-
- TScheduledEventsList TTestActorRuntimeBase::CaptureScheduledEvents() {
- TGuard<TMutex> guard(Mutex);
- TScheduledEventsList result;
- for (auto& mbox : Mailboxes) {
- mbox.second->CaptureScheduled(result);
- }
-
- return result;
- }
-
- bool TTestActorRuntimeBase::DispatchEvents(const TDispatchOptions& options) {
- return DispatchEvents(options, TInstant::Max());
- }
-
- bool TTestActorRuntimeBase::DispatchEvents(const TDispatchOptions& options, TDuration simTimeout) {
- return DispatchEvents(options, TInstant::MicroSeconds(CurrentTimestamp) + simTimeout);
- }
-
- bool TTestActorRuntimeBase::DispatchEvents(const TDispatchOptions& options, TInstant simDeadline) {
- TGuard<TMutex> guard(Mutex);
- return DispatchEventsInternal(options, simDeadline);
- }
-
- // Mutex must be locked by caller!
- bool TTestActorRuntimeBase::DispatchEventsInternal(const TDispatchOptions& options, TInstant simDeadline) {
- TDispatchContext localContext;
- localContext.Options = &options;
- localContext.PrevContext = nullptr;
- bool verbose = !options.Quiet && VERBOSE;
-
- struct TDispatchContextSetter {
- TDispatchContextSetter(TTestActorRuntimeBase& runtime, TDispatchContext& lastContext)
- : Runtime(runtime)
- {
- lastContext.PrevContext = Runtime.CurrentDispatchContext;
- Runtime.CurrentDispatchContext = &lastContext;
- }
-
- ~TDispatchContextSetter() {
- Runtime.CurrentDispatchContext = Runtime.CurrentDispatchContext->PrevContext;
- }
-
- TTestActorRuntimeBase& Runtime;
- } DispatchContextSetter(*this, localContext);
-
- TInstant dispatchTime = TInstant::MicroSeconds(0);
- TInstant deadline = dispatchTime + DispatchTimeout;
- const TDuration scheduledEventsInspectInterval = TDuration::MilliSeconds(10);
- TInstant inspectScheduledEventsAt = dispatchTime + scheduledEventsInspectInterval;
- if (verbose) {
- Cerr << "Start dispatch at " << TInstant::MicroSeconds(CurrentTimestamp) << ", deadline is " << deadline << "\n";
- }
-
- struct TTempEdgeEventsCaptor {
- TTempEdgeEventsCaptor(TTestActorRuntimeBase& runtime)
- : Runtime(runtime)
- , HasEvents(false)
- {
- for (auto edgeActor : Runtime.EdgeActors) {
- TEventsList events;
- Runtime.GetMailbox(edgeActor.NodeId(), edgeActor.Hint()).Capture(events);
- auto mboxId = TEventMailboxId(edgeActor.NodeId(), edgeActor.Hint());
- auto storeIt = Store.find(mboxId);
- Y_ABORT_UNLESS(storeIt == Store.end());
- storeIt = Store.insert(std::make_pair(mboxId, new TEventMailBox)).first;
- storeIt->second->PushFront(events);
- if (!events.empty())
- HasEvents = true;
- }
- }
-
- ~TTempEdgeEventsCaptor() {
- for (auto edgeActor : Runtime.EdgeActors) {
- auto mboxId = TEventMailboxId(edgeActor.NodeId(), edgeActor.Hint());
- auto storeIt = Store.find(mboxId);
- if (storeIt == Store.end()) {
- continue;
- }
-
- TEventsList events;
- storeIt->second->Capture(events);
- Runtime.GetMailbox(edgeActor.NodeId(), edgeActor.Hint()).PushFront(events);
- }
- }
-
- TTestActorRuntimeBase& Runtime;
- TEventMailBoxList Store;
- bool HasEvents;
- };
-
- TEventMailBoxList restrictedMailboxes;
- const bool useRestrictedMailboxes = !options.OnlyMailboxes.empty();
- for (auto mailboxId : options.OnlyMailboxes) {
- auto it = Mailboxes.find(mailboxId);
- if (it == Mailboxes.end()) {
- it = Mailboxes.insert(std::make_pair(mailboxId, new TEventMailBox())).first;
- }
-
- restrictedMailboxes.insert(std::make_pair(mailboxId, it->second));
- }
-
- TAutoPtr<TTempEdgeEventsCaptor> tempEdgeEventsCaptor;
- if (!restrictedMailboxes) {
- tempEdgeEventsCaptor.Reset(new TTempEdgeEventsCaptor(*this));
- }
-
- TEventMailBoxList& currentMailboxes = useRestrictedMailboxes ? restrictedMailboxes : Mailboxes;
- while (!currentMailboxes.empty()) {
- bool hasProgress = true;
- while (hasProgress) {
- ++DispatchCyclesCount;
- hasProgress = false;
-
- ui64 eventsToDispatch = 0;
- for (auto mboxIt = currentMailboxes.begin(); mboxIt != currentMailboxes.end(); ++mboxIt) {
- if (mboxIt->second->IsActive(TInstant::MicroSeconds(CurrentTimestamp))) {
- eventsToDispatch += mboxIt->second->GetSentEventCount();
- }
- }
- ui32 eventsDispatched = 0;
-
- //TODO: count events before each cycle, break after dispatching that much events
- bool isEmpty = false;
- while (!isEmpty && eventsDispatched < eventsToDispatch) {
- ui64 mailboxCount = currentMailboxes.size();
- ui64 startWith = mailboxCount ? DispatcherRandomProvider->GenRand64() % mailboxCount : 0ull;
- auto startWithMboxIt = currentMailboxes.begin();
- for (ui64 i = 0; i < startWith; ++i) {
- ++startWithMboxIt;
- }
- auto endWithMboxIt = startWithMboxIt;
-
- isEmpty = true;
- auto mboxIt = startWithMboxIt;
- TDeque<TEventMailboxId> suspectedBoxes;
- while (true) {
- auto& mbox = *mboxIt;
- bool isIgnored = true;
- if (!mbox.second->IsEmpty()) {
- HandleNonEmptyMailboxesForEachContext(mbox.first);
- if (mbox.second->IsActive(TInstant::MicroSeconds(CurrentTimestamp))) {
-
- bool isEdgeMailbox = false;
- if (EdgeActorByMailbox.FindPtr(TEventMailboxId(mbox.first.NodeId, mbox.first.Hint))) {
- isEdgeMailbox = true;
- TEventsList events;
- mbox.second->Capture(events);
-
- TEventsList eventsToPush;
- for (auto& ev : events) {
- TInverseGuard<TMutex> inverseGuard(Mutex);
-
- for (auto observer : ObserverFuncs) {
- observer(ev);
- if (!ev) break;
- }
-
- if(ev && ObserverFunc(ev) != EEventAction::DROP && ev)
- eventsToPush.push_back(ev);
- }
- mbox.second->PushFront(eventsToPush);
- }
-
- if (!isEdgeMailbox) {
- isEmpty = false;
- isIgnored = false;
- ++eventsDispatched;
- ++DispatchedEventsCount;
- if (DispatchedEventsCount > DispatchedEventsLimit) {
- ythrow TWithBackTrace<yexception>() << "Dispatched "
- << DispatchedEventsLimit << " events, limit reached.";
- }
-
- auto ev = mbox.second->Pop();
- if (BlockedOutput.find(ev->Sender) == BlockedOutput.end()) {
- //UpdateCurrentTime(TInstant::MicroSeconds(CurrentTimestamp + 10));
- if (verbose) {
- Cerr << "Process event at " << TInstant::MicroSeconds(CurrentTimestamp) << ", ";
- PrintEvent(ev, this);
- }
- }
-
- hasProgress = true;
- EEventAction action = EEventAction::PROCESS;
- {
- TInverseGuard<TMutex> inverseGuard(Mutex);
-
- for (auto observer : ObserverFuncs) {
- observer(ev);
- if(!ev) break;
- }
-
- if (ev)
- action = ObserverFunc(ev);
- }
-
- if (ev) {
- switch (action) {
- case EEventAction::PROCESS:
- UpdateFinalEventsStatsForEachContext(*ev);
- SendInternal(ev.Release(), mbox.first.NodeId - FirstNodeId, false);
- break;
- case EEventAction::DROP:
- // do nothing
- break;
- case EEventAction::RESCHEDULE: {
- TInstant deadline = TInstant::MicroSeconds(CurrentTimestamp) + ReschedulingDelay;
- mbox.second->Freeze(deadline);
- mbox.second->PushFront(ev);
- break;
- }
- default:
- Y_ABORT("Unknown action");
- }
- }
- }
- }
-
- }
- Y_ABORT_UNLESS(mboxIt != currentMailboxes.end());
- if (!isIgnored && !CurrentDispatchContext->PrevContext && !restrictedMailboxes &&
- mboxIt->second->IsEmpty() &&
- mboxIt->second->IsScheduledEmpty() &&
- mboxIt->second->IsActive(TInstant::MicroSeconds(CurrentTimestamp))) {
- suspectedBoxes.push_back(mboxIt->first);
- }
- ++mboxIt;
- if (mboxIt == currentMailboxes.end()) {
- mboxIt = currentMailboxes.begin();
- }
- Y_ABORT_UNLESS(endWithMboxIt != currentMailboxes.end());
- if (mboxIt == endWithMboxIt) {
- break;
- }
- }
-
- for (auto id : suspectedBoxes) {
- auto it = currentMailboxes.find(id);
- if (it != currentMailboxes.end() && it->second->IsEmpty() && it->second->IsScheduledEmpty() &&
- it->second->IsActive(TInstant::MicroSeconds(CurrentTimestamp))) {
- currentMailboxes.erase(it);
- }
- }
- }
- }
-
- if (localContext.FinalEventFound) {
- return true;
- }
-
- if (!localContext.FoundNonEmptyMailboxes.empty())
- return true;
-
- if (options.CustomFinalCondition && options.CustomFinalCondition())
- return true;
-
- if (options.FinalEvents.empty()) {
- for (auto& mbox : currentMailboxes) {
- if (!mbox.second->IsActive(TInstant::MicroSeconds(CurrentTimestamp)))
- continue;
-
- if (!mbox.second->IsEmpty()) {
- if (verbose) {
- Cerr << "Dispatch complete with non-empty queue at " << TInstant::MicroSeconds(CurrentTimestamp) << "\n";
- }
-
- return true;
- }
- }
- }
-
- if (TInstant::MicroSeconds(CurrentTimestamp) > simDeadline) {
- return false;
- }
-
- if (dispatchTime >= deadline) {
- if (verbose) {
- Cerr << "Reach deadline at " << TInstant::MicroSeconds(CurrentTimestamp) << "\n";
- }
-
- ythrow TWithBackTrace<TEmptyEventQueueException>();
- }
-
- if (!options.Quiet && dispatchTime >= inspectScheduledEventsAt) {
- inspectScheduledEventsAt = dispatchTime + scheduledEventsInspectInterval;
- bool isEmpty = true;
- TMaybe<TInstant> nearestMailboxDeadline;
- TVector<TIntrusivePtr<TEventMailBox>> nextScheduleMboxes;
- TMaybe<TInstant> nextScheduleDeadline;
- for (auto& mbox : currentMailboxes) {
- if (!mbox.second->IsActive(TInstant::MicroSeconds(CurrentTimestamp))) {
- if (!nearestMailboxDeadline.Defined() || *nearestMailboxDeadline.Get() > mbox.second->GetInactiveUntil()) {
- nearestMailboxDeadline = mbox.second->GetInactiveUntil();
- }
-
- continue;
- }
-
- if (mbox.second->IsScheduledEmpty())
- continue;
-
- auto firstScheduleDeadline = mbox.second->GetFirstScheduleDeadline();
- if (!nextScheduleDeadline || firstScheduleDeadline < *nextScheduleDeadline) {
- nextScheduleMboxes.clear();
- nextScheduleMboxes.emplace_back(mbox.second);
- nextScheduleDeadline = firstScheduleDeadline;
- } else if (firstScheduleDeadline == *nextScheduleDeadline) {
- nextScheduleMboxes.emplace_back(mbox.second);
- }
- }
-
- for (const auto& nextScheduleMbox : nextScheduleMboxes) {
- TEventsList selectedEvents;
- TScheduledEventsList capturedScheduledEvents;
- nextScheduleMbox->CaptureScheduled(capturedScheduledEvents);
- ScheduledEventsSelectorFunc(*this, capturedScheduledEvents, selectedEvents);
- nextScheduleMbox->PushScheduled(capturedScheduledEvents);
- for (auto& event : selectedEvents) {
- if (verbose && (BlockedOutput.find(event->Sender) == BlockedOutput.end())) {
- Cerr << "Selected scheduled event at " << TInstant::MicroSeconds(CurrentTimestamp) << ", ";
- PrintEvent(event, this);
- }
-
- nextScheduleMbox->Send(event);
- isEmpty = false;
- }
- }
-
- if (!isEmpty) {
- if (verbose) {
- Cerr << "Process selected events at " << TInstant::MicroSeconds(CurrentTimestamp) << "\n";
- }
-
- deadline = dispatchTime + DispatchTimeout;
- continue;
- }
-
- if (nearestMailboxDeadline.Defined()) {
- if (verbose) {
- Cerr << "Forward time to " << *nearestMailboxDeadline.Get() << "\n";
- }
-
- UpdateCurrentTime(*nearestMailboxDeadline.Get());
- continue;
- }
- }
-
- TDuration waitDelay = TDuration::MilliSeconds(10);
- dispatchTime += waitDelay;
- MailboxesHasEvents.WaitT(Mutex, waitDelay);
- }
- return false;
- }
-
- void TTestActorRuntimeBase::HandleNonEmptyMailboxesForEachContext(TEventMailboxId mboxId) {
- TDispatchContext* context = CurrentDispatchContext;
- while (context) {
- const auto& nonEmptyMailboxes = context->Options->NonEmptyMailboxes;
- if (Find(nonEmptyMailboxes.begin(), nonEmptyMailboxes.end(), mboxId) != nonEmptyMailboxes.end()) {
- context->FoundNonEmptyMailboxes.insert(mboxId);
- }
-
- context = context->PrevContext;
- }
- }
-
- void TTestActorRuntimeBase::UpdateFinalEventsStatsForEachContext(IEventHandle& ev) {
- TDispatchContext* context = CurrentDispatchContext;
- while (context) {
- for (const auto& finalEvent : context->Options->FinalEvents) {
- if (finalEvent.EventCheck(ev)) {
- auto& freq = context->FinalEventFrequency[&finalEvent];
- if (++freq >= finalEvent.RequiredCount) {
- context->FinalEventFound = true;
- }
- }
- }
-
- context = context->PrevContext;
- }
- }
-
- void TTestActorRuntimeBase::Send(const TActorId& recipient, const TActorId& sender, TAutoPtr<IEventBase> ev, ui32 senderNodeIndex, bool viaActorSystem) {
- Send(new IEventHandle(recipient, sender, ev.Release()), senderNodeIndex, viaActorSystem);
- }
-
- void TTestActorRuntimeBase::Send(TAutoPtr<IEventHandle> ev, ui32 senderNodeIndex, bool viaActorSystem) {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(senderNodeIndex < NodeCount, "senderNodeIndex# %" PRIu32 " < NodeCount# %" PRIu32,
- senderNodeIndex, NodeCount);
- SendInternal(ev, senderNodeIndex, viaActorSystem);
- }
-
- void TTestActorRuntimeBase::SendAsync(TAutoPtr<IEventHandle> ev, ui32 senderNodeIndex) {
- Send(ev, senderNodeIndex, true);
- }
-
- void TTestActorRuntimeBase::Schedule(TAutoPtr<IEventHandle> ev, const TDuration& duration, ui32 nodeIndex) {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(nodeIndex < NodeCount);
- ui32 nodeId = FirstNodeId + nodeIndex;
- ui32 mailboxHint = ev->GetRecipientRewrite().Hint();
- TInstant deadline = TInstant::MicroSeconds(CurrentTimestamp) + duration;
- GetMailbox(nodeId, mailboxHint).Schedule(TScheduledEventQueueItem(deadline, ev, nullptr));
- if (VERBOSE)
- Cerr << "Event was added to scheduled queue\n";
- }
-
- void TTestActorRuntimeBase::ClearCounters() {
- TGuard<TMutex> guard(Mutex);
- EvCounters.clear();
- }
-
- ui64 TTestActorRuntimeBase::GetCounter(ui32 evType) const {
- TGuard<TMutex> guard(Mutex);
- auto it = EvCounters.find(evType);
- if (it == EvCounters.end())
- return 0;
-
- return it->second;
- }
-
- TActorId TTestActorRuntimeBase::GetLocalServiceId(const TActorId& serviceId, ui32 nodeIndex) {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(nodeIndex < NodeCount);
- TNodeDataBase* node = Nodes[FirstNodeId + nodeIndex].Get();
- return node->ActorSystem->LookupLocalService(serviceId);
- }
-
- void TTestActorRuntimeBase::WaitForEdgeEvents(TEventFilter filter, const TSet<TActorId>& edgeFilter, TDuration simTimeout) {
- TGuard<TMutex> guard(Mutex);
- ui32 dispatchCount = 0;
- if (!edgeFilter.empty()) {
- for (auto edgeActor : edgeFilter) {
- Y_ABORT_UNLESS(EdgeActors.contains(edgeActor), "%s is not an edge actor", ToString(edgeActor).data());
- }
- }
- const TSet<TActorId>& edgeActors = edgeFilter.empty() ? EdgeActors : edgeFilter;
- TInstant deadline = TInstant::MicroSeconds(CurrentTimestamp) + simTimeout;
- for (;;) {
- for (auto edgeActor : edgeActors) {
- TEventsList events;
- auto& mbox = GetMailbox(edgeActor.NodeId(), edgeActor.Hint());
- bool foundEvent = false;
- mbox.Capture(events);
- for (auto& ev : events) {
- if (filter(*this, ev)) {
- foundEvent = true;
- break;
- }
- }
-
- mbox.PushFront(events);
- if (foundEvent)
- return;
- }
-
- ++dispatchCount;
- {
- if (!DispatchEventsInternal(TDispatchOptions(), deadline)) {
- return; // Timed out; event was not found
- }
- }
-
- Y_ABORT_UNLESS(dispatchCount < 1000, "Hard limit to prevent endless loop");
- }
- }
-
- TActorId TTestActorRuntimeBase::GetInterconnectProxy(ui32 nodeIndexFrom, ui32 nodeIndexTo) {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(nodeIndexFrom < NodeCount);
- Y_ABORT_UNLESS(nodeIndexTo < NodeCount);
- Y_ABORT_UNLESS(nodeIndexFrom != nodeIndexTo);
- TNodeDataBase* node = Nodes[FirstNodeId + nodeIndexFrom].Get();
- return node->ActorSystem->InterconnectProxy(FirstNodeId + nodeIndexTo);
- }
-
- void TTestActorRuntimeBase::BlockOutputForActor(const TActorId& actorId) {
- TGuard<TMutex> guard(Mutex);
- BlockedOutput.insert(actorId);
- }
-
- void TTestActorRuntimeBase::SetDispatcherRandomSeed(TInstant time, ui64 iteration) {
- ui64 days = (time.Hours() / 24);
- DispatcherRandomSeed = (days << 32) ^ iteration;
- DispatcherRandomProvider = CreateDeterministicRandomProvider(DispatcherRandomSeed);
- }
-
- IActor* TTestActorRuntimeBase::FindActor(const TActorId& actorId, ui32 nodeIndex) const {
- TGuard<TMutex> guard(Mutex);
- if (nodeIndex == Max<ui32>()) {
- Y_ABORT_UNLESS(actorId.NodeId());
- nodeIndex = actorId.NodeId() - FirstNodeId;
- }
-
- Y_ABORT_UNLESS(nodeIndex < NodeCount);
- auto nodeIt = Nodes.find(FirstNodeId + nodeIndex);
- Y_ABORT_UNLESS(nodeIt != Nodes.end());
- TNodeDataBase* node = nodeIt->second.Get();
- return FindActor(actorId, node);
- }
-
- void TTestActorRuntimeBase::EnableScheduleForActor(const TActorId& actorId, bool allow) {
- TGuard<TMutex> guard(Mutex);
- if (allow) {
- if (VERBOSE) {
- Cerr << "Actor " << actorId << " added to schedule whitelist";
- }
- ScheduleWhiteList.insert(actorId);
- } else {
- if (VERBOSE) {
- Cerr << "Actor " << actorId << " removed from schedule whitelist";
- }
- ScheduleWhiteList.erase(actorId);
- }
- }
-
- bool TTestActorRuntimeBase::IsScheduleForActorEnabled(const TActorId& actorId) const {
- TGuard<TMutex> guard(Mutex);
- return ScheduleWhiteList.find(actorId) != ScheduleWhiteList.end();
- }
-
- TIntrusivePtr<NMonitoring::TDynamicCounters> TTestActorRuntimeBase::GetDynamicCounters(ui32 nodeIndex) {
- TGuard<TMutex> guard(Mutex);
- Y_ABORT_UNLESS(nodeIndex < NodeCount);
- ui32 nodeId = FirstNodeId + nodeIndex;
- TNodeDataBase* node = Nodes[nodeId].Get();
- return node->DynamicCounters;
- }
-
- void TTestActorRuntimeBase::SetupMonitoring() {
- NeedMonitoring = true;
- }
-
- void TTestActorRuntimeBase::SendInternal(TAutoPtr<IEventHandle> ev, ui32 nodeIndex, bool viaActorSystem) {
- Y_ABORT_UNLESS(nodeIndex < NodeCount);
- ui32 nodeId = FirstNodeId + nodeIndex;
- TNodeDataBase* node = Nodes[nodeId].Get();
- ui32 targetNode = ev->GetRecipientRewrite().NodeId();
- ui32 targetNodeIndex;
- if (targetNode == 0) {
- targetNodeIndex = nodeIndex;
- } else {
- targetNodeIndex = targetNode - FirstNodeId;
- Y_ABORT_UNLESS(targetNodeIndex < NodeCount);
- }
-
- if (viaActorSystem || UseRealThreads || ev->GetRecipientRewrite().IsService() || (targetNodeIndex != nodeIndex)) {
- node->ActorSystem->Send(ev);
- return;
- }
-
- Y_ABORT_UNLESS(!ev->GetRecipientRewrite().IsService() && (targetNodeIndex == nodeIndex));
-
- if (!AllowSendFrom(node, ev)) {
- return;
- }
-
- ui32 mailboxHint = ev->GetRecipientRewrite().Hint();
- TEventMailBox& mbox = GetMailbox(nodeId, mailboxHint);
- if (!mbox.IsActive(TInstant::MicroSeconds(CurrentTimestamp))) {
- mbox.PushFront(ev);
- return;
- }
-
- ui64 recipientLocalId = ev->GetRecipientRewrite().LocalId();
- if ((BlockedOutput.find(ev->Sender) == BlockedOutput.end()) && VERBOSE) {
- Cerr << "Send event, ";
- PrintEvent(ev, this);
- }
-
- EvCounters[ev->GetTypeRewrite()]++;
-
- TMailboxHeader* mailbox = node->MailboxTable->Get(mailboxHint);
- IActor* recipientActor = mailbox->FindActor(recipientLocalId);
- if (recipientActor) {
- // Save actorId by value in order to prevent ctx from being invalidated during another Send call.
- TActorId actorId = ev->GetRecipientRewrite();
- node->ActorToActorId[recipientActor] = ev->GetRecipientRewrite();
- TActorContext ctx(*mailbox, *node->ExecutorThread, GetCycleCountFast(), actorId);
- TActivationContext *prevTlsActivationContext = TlsActivationContext;
- TlsActivationContext = &ctx;
- CurrentRecipient = actorId;
- {
- TInverseGuard<TMutex> inverseGuard(Mutex);
-#ifdef USE_ACTOR_CALLSTACK
- TCallstack::GetTlsCallstack() = ev->Callstack;
- TCallstack::GetTlsCallstack().SetLinesToSkip();
-#endif
- recipientActor->Receive(ev);
- node->ExecutorThread->DropUnregistered();
- }
- CurrentRecipient = TActorId();
- TlsActivationContext = prevTlsActivationContext;
- } else {
- if (VERBOSE) {
- Cerr << "Failed to find actor with local id: " << recipientLocalId << "\n";
- }
-
- auto fw = IEventHandle::ForwardOnNondelivery(ev, TEvents::TEvUndelivered::ReasonActorUnknown);
- node->ActorSystem->Send(fw);
- }
- }
-
- IActor* TTestActorRuntimeBase::FindActor(const TActorId& actorId, TNodeDataBase* node) const {
- ui32 mailboxHint = actorId.Hint();
- ui64 localId = actorId.LocalId();
- TMailboxHeader* mailbox = node->MailboxTable->Get(mailboxHint);
- IActor* actor = mailbox->FindActor(localId);
- return actor;
- }
-
- THolder<TActorSystemSetup> TTestActorRuntimeBase::MakeActorSystemSetup(ui32 nodeIndex, TNodeDataBase* node) {
- THolder<TActorSystemSetup> setup(new TActorSystemSetup);
- setup->NodeId = FirstNodeId + nodeIndex;
-
- if (UseRealThreads) {
- setup->ExecutorsCount = 5;
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[5]);
- 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, 1));
- setup->Executors[3].Reset(new TBasicExecutorPool(3, 2, 20));
- setup->Executors[4].Reset(new TBasicExecutorPool(4, 1, 20));
- setup->Scheduler.Reset(new TBasicSchedulerThread(TSchedulerConfig(512, 100)));
- } else {
- setup->ExecutorsCount = 1;
- setup->Scheduler.Reset(new TSchedulerThreadStub(this, node));
- setup->Executors.Reset(new TAutoPtr<IExecutorPool>[1]);
- setup->Executors[0].Reset(new TExecutorPoolStub(this, nodeIndex, node, 0));
- }
-
- InitActorSystemSetup(*setup);
-
- return setup;
- }
-
- THolder<TActorSystem> TTestActorRuntimeBase::MakeActorSystem(ui32 nodeIndex, TNodeDataBase* node) {
- auto setup = MakeActorSystemSetup(nodeIndex, node);
-
- node->ExecutorPools.resize(setup->ExecutorsCount);
- for (ui32 i = 0; i < setup->ExecutorsCount; ++i) {
- node->ExecutorPools[i] = setup->Executors[i].Get();
- }
-
- const auto& interconnectCounters = GetCountersForComponent(node->DynamicCounters, "interconnect");
-
- for (const auto& cmd : node->LocalServices) {
- setup->LocalServices.emplace_back(cmd.first, TActorSetupCmd(cmd.second.Actor, cmd.second.MailboxType, cmd.second.PoolId));
- }
- setup->Interconnect.ProxyActors.resize(FirstNodeId + NodeCount);
- const TActorId nameserviceId = GetNameserviceActorId();
-
- TIntrusivePtr<TInterconnectProxyCommon> common;
- common.Reset(new TInterconnectProxyCommon);
- common->NameserviceId = nameserviceId;
- common->MonCounters = interconnectCounters;
- 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->ClusterUUID = ClusterUUID;
- common->AcceptUUID = {ClusterUUID};
-
- if (ICCommonSetupper) {
- ICCommonSetupper(nodeIndex, common);
- }
-
- for (ui32 proxyNodeIndex = 0; proxyNodeIndex < NodeCount; ++proxyNodeIndex) {
- if (proxyNodeIndex == nodeIndex)
- continue;
-
- 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()};
- }
-
- 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,
- logBackend, GetCountersForComponent(node->DynamicCounters, "utils"));
- NActors::TActorSetupCmd loggerActorCmd(loggerActor, NActors::TMailboxType::Simple, node->GetLoggerPoolId());
- std::pair<NActors::TActorId, NActors::TActorSetupCmd> loggerActorPair(node->LogSettings->LoggerActorId, std::move(loggerActorCmd));
- setup->LocalServices.push_back(std::move(loggerActorPair));
- }
-
- return THolder<TActorSystem>(new TActorSystem(setup, node->GetAppData(), node->LogSettings));
- }
-
- TActorSystem* TTestActorRuntimeBase::SingleSys() const {
- Y_ABORT_UNLESS(Nodes.size() == 1, "Works only for single system env");
-
- return Nodes.begin()->second->ActorSystem.Get();
- }
-
- TActorSystem* TTestActorRuntimeBase::GetAnyNodeActorSystem() {
- for (auto& x : Nodes) {
- return x.second->ActorSystem.Get();
- }
- Y_ABORT("Don't use this method.");
- }
-
- TActorSystem* TTestActorRuntimeBase::GetActorSystem(ui32 nodeId) {
- auto it = Nodes.find(GetNodeId(nodeId));
- Y_ABORT_UNLESS(it != Nodes.end());
- return it->second->ActorSystem.Get();
- }
-
-
- TEventMailBox& TTestActorRuntimeBase::GetMailbox(ui32 nodeId, ui32 hint) {
- TGuard<TMutex> guard(Mutex);
- auto mboxId = TEventMailboxId(nodeId, hint);
- auto it = Mailboxes.find(mboxId);
- if (it == Mailboxes.end()) {
- it = Mailboxes.insert(std::make_pair(mboxId, new TEventMailBox())).first;
- }
-
- return *it->second;
- }
-
- void TTestActorRuntimeBase::ClearMailbox(ui32 nodeId, ui32 hint) {
- TGuard<TMutex> guard(Mutex);
- auto mboxId = TEventMailboxId(nodeId, hint);
- Mailboxes.erase(mboxId);
- }
-
- TString TTestActorRuntimeBase::GetActorName(const TActorId& actorId) const {
- auto it = ActorNames.find(actorId);
- if (it != ActorNames.end())
- return it->second;
- return actorId.ToString();
- }
-
- struct TStrandingActorDecoratorContext : public TThrRefBase {
- TStrandingActorDecoratorContext()
- : Queue(new TQueueType)
- {
- }
-
- typedef TOneOneQueueInplace<IEventHandle*, 32> TQueueType;
- TAutoPtr<TQueueType, TQueueType::TPtrCleanDestructor> Queue;
- };
-
- class TStrandingActorDecorator : public TActorBootstrapped<TStrandingActorDecorator> {
- public:
- class TReplyActor : public TActor<TReplyActor> {
- public:
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::TEST_ACTOR_RUNTIME;
- }
-
- TReplyActor(TStrandingActorDecorator* owner)
- : TActor(&TReplyActor::StateFunc)
- , Owner(owner)
- {
- }
-
- STFUNC(StateFunc);
-
- private:
- TStrandingActorDecorator* const Owner;
- };
-
- static constexpr EActivityType ActorActivityType() {
- return EActivityType::TEST_ACTOR_RUNTIME;
- }
-
- TStrandingActorDecorator(const TActorId& delegatee, bool isSync, const TVector<TActorId>& additionalActors,
- TSimpleSharedPtr<TStrandingActorDecoratorContext> context, TTestActorRuntimeBase* runtime,
- TReplyCheckerCreator createReplyChecker)
- : Delegatee(delegatee)
- , IsSync(isSync)
- , AdditionalActors(additionalActors)
- , Context(context)
- , HasReply(false)
- , Runtime(runtime)
- , ReplyChecker(createReplyChecker())
- {
- if (IsSync) {
- Y_ABORT_UNLESS(!runtime->IsRealThreads());
- }
- }
-
- void Bootstrap(const TActorContext& ctx) {
- Become(&TStrandingActorDecorator::StateFunc);
- ReplyId = ctx.RegisterWithSameMailbox(new TReplyActor(this));
- DelegateeOptions.OnlyMailboxes.push_back(TEventMailboxId(Delegatee.NodeId(), Delegatee.Hint()));
- for (const auto& actor : AdditionalActors) {
- DelegateeOptions.OnlyMailboxes.push_back(TEventMailboxId(actor.NodeId(), actor.Hint()));
- }
-
- DelegateeOptions.OnlyMailboxes.push_back(TEventMailboxId(ReplyId.NodeId(), ReplyId.Hint()));
- DelegateeOptions.NonEmptyMailboxes.push_back(TEventMailboxId(ReplyId.NodeId(), ReplyId.Hint()));
- DelegateeOptions.Quiet = true;
- }
-
- STFUNC(StateFunc) {
- bool wasEmpty = !Context->Queue->Head();
- Context->Queue->Push(ev.Release());
- if (wasEmpty) {
- SendHead(ActorContext());
- }
- }
-
- STFUNC(Reply) {
- Y_ABORT_UNLESS(!HasReply);
- IEventHandle *requestEv = Context->Queue->Head();
- TActorId originalSender = requestEv->Sender;
- HasReply = !ReplyChecker->IsWaitingForMoreResponses(ev.Get());
- if (HasReply) {
- delete Context->Queue->Pop();
- }
- auto ctx(ActorContext());
- ctx.ExecutorThread.Send(IEventHandle::Forward(ev, originalSender));
- if (!IsSync && Context->Queue->Head()) {
- SendHead(ctx);
- }
- }
-
- private:
- void SendHead(const TActorContext& ctx) {
- if (!IsSync) {
- ctx.ExecutorThread.Send(GetForwardedEvent().Release());
- } else {
- while (Context->Queue->Head()) {
- HasReply = false;
- ctx.ExecutorThread.Send(GetForwardedEvent().Release());
- int count = 100;
- while (!HasReply && count > 0) {
- try {
- Runtime->DispatchEvents(DelegateeOptions);
- } catch (TEmptyEventQueueException&) {
- count--;
- Cerr << "No reply" << Endl;
- }
- }
-
- Runtime->UpdateCurrentTime(Runtime->GetCurrentTime() + TDuration::MicroSeconds(1000));
- }
- }
- }
-
- TAutoPtr<IEventHandle> GetForwardedEvent() {
- IEventHandle* ev = Context->Queue->Head();
- 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);
-
- return forwardedEv;
- }
- private:
- const TActorId Delegatee;
- const bool IsSync;
- const TVector<TActorId> AdditionalActors;
- TSimpleSharedPtr<TStrandingActorDecoratorContext> Context;
- TActorId ReplyId;
- bool HasReply;
- TDispatchOptions DelegateeOptions;
- TTestActorRuntimeBase* Runtime;
- THolder<IReplyChecker> ReplyChecker;
- };
-
- void TStrandingActorDecorator::TReplyActor::StateFunc(STFUNC_SIG) {
- Owner->Reply(ev);
- }
-
- class TStrandingDecoratorFactory : public IStrandingDecoratorFactory {
- public:
- TStrandingDecoratorFactory(TTestActorRuntimeBase* runtime,
- TReplyCheckerCreator createReplyChecker)
- : Context(new TStrandingActorDecoratorContext())
- , Runtime(runtime)
- , CreateReplyChecker(createReplyChecker)
- {
- }
-
- IActor* Wrap(const TActorId& delegatee, bool isSync, const TVector<TActorId>& additionalActors) override {
- return new TStrandingActorDecorator(delegatee, isSync, additionalActors, Context, Runtime,
- CreateReplyChecker);
- }
-
- private:
- TSimpleSharedPtr<TStrandingActorDecoratorContext> Context;
- TTestActorRuntimeBase* Runtime;
- TReplyCheckerCreator CreateReplyChecker;
- };
-
- TAutoPtr<IStrandingDecoratorFactory> CreateStrandingDecoratorFactory(TTestActorRuntimeBase* runtime,
- TReplyCheckerCreator createReplyChecker) {
- return TAutoPtr<IStrandingDecoratorFactory>(new TStrandingDecoratorFactory(runtime, createReplyChecker));
- }
-
- ui64 DefaultRandomSeed = 9999;
-}
diff --git a/library/cpp/actors/testlib/test_runtime.h b/library/cpp/actors/testlib/test_runtime.h
deleted file mode 100644
index f46d3906e4..0000000000
--- a/library/cpp/actors/testlib/test_runtime.h
+++ /dev/null
@@ -1,814 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/actorsystem.h>
-#include <library/cpp/actors/core/log.h>
-#include <library/cpp/actors/core/events.h>
-#include <library/cpp/actors/core/executor_thread.h>
-#include <library/cpp/actors/core/mailbox.h>
-#include <library/cpp/actors/core/monotonic_provider.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/random_provider/random_provider.h>
-#include <library/cpp/time_provider/time_provider.h>
-#include <library/cpp/testing/unittest/tests_data.h>
-
-#include <util/datetime/base.h>
-#include <util/folder/tempdir.h>
-#include <util/generic/deque.h>
-#include <util/generic/hash.h>
-#include <util/generic/noncopyable.h>
-#include <util/generic/ptr.h>
-#include <util/generic/queue.h>
-#include <util/generic/set.h>
-#include <util/generic/vector.h>
-#include <util/system/defaults.h>
-#include <util/system/mutex.h>
-#include <util/system/condvar.h>
-#include <util/system/thread.h>
-#include <util/system/sanitizers.h>
-#include <util/system/valgrind.h>
-#include <utility>
-
-#include <functional>
-
-const TDuration DEFAULT_DISPATCH_TIMEOUT = NSan::PlainOrUnderSanitizer(
- NValgrind::PlainOrUnderValgrind(TDuration::Seconds(60), TDuration::Seconds(120)),
- TDuration::Seconds(120)
-);
-
-
-namespace NActors {
- struct THeSingleSystemEnv { };
-
- struct TTestActorSetupCmd { // like TActorSetupCmd, but not owning the Actor
- TTestActorSetupCmd(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId)
- : MailboxType(mailboxType)
- , PoolId(poolId)
- , Actor(actor)
- {
- }
-
- TTestActorSetupCmd(TActorSetupCmd cmd)
- : MailboxType(cmd.MailboxType)
- , PoolId(cmd.PoolId)
- , Actor(cmd.Actor.release())
- {
- }
-
- TMailboxType::EType MailboxType;
- ui32 PoolId;
- IActor* Actor;
- };
-
- struct TEventMailboxId {
- TEventMailboxId()
- : NodeId(0)
- , Hint(0)
- {
- }
-
- TEventMailboxId(ui32 nodeId, ui32 hint)
- : NodeId(nodeId)
- , Hint(hint)
- {
- }
-
- bool operator<(const TEventMailboxId& other) const {
- return (NodeId < other.NodeId) || (NodeId == other.NodeId) && (Hint < other.Hint);
- }
-
- bool operator==(const TEventMailboxId& other) const {
- return (NodeId == other.NodeId) && (Hint == other.Hint);
- }
-
- struct THash {
- ui64 operator()(const TEventMailboxId& mboxId) const noexcept {
- return mboxId.NodeId * 31ULL + mboxId.Hint;
- }
- };
-
- ui32 NodeId;
- ui32 Hint;
- };
-
- struct TDispatchOptions {
- struct TFinalEventCondition {
- std::function<bool(IEventHandle& ev)> EventCheck;
- ui32 RequiredCount;
-
- TFinalEventCondition(ui32 eventType, ui32 requiredCount = 1)
- : EventCheck([eventType](IEventHandle& ev) -> bool { return ev.GetTypeRewrite() == eventType; })
- , RequiredCount(requiredCount)
- {
- }
-
- TFinalEventCondition(std::function<bool(IEventHandle& ev)> eventCheck, ui32 requiredCount = 1)
- : EventCheck(eventCheck)
- , RequiredCount(requiredCount)
- {
- }
- };
-
- TVector<TFinalEventCondition> FinalEvents;
- TVector<TEventMailboxId> NonEmptyMailboxes;
- TVector<TEventMailboxId> OnlyMailboxes;
- std::function<bool()> CustomFinalCondition;
- bool Quiet = false;
- };
-
- struct TScheduledEventQueueItem {
- TInstant Deadline;
- TAutoPtr<IEventHandle> Event;
- TAutoPtr<TSchedulerCookieHolder> Cookie;
- ui64 UniqueId;
-
- TScheduledEventQueueItem(TInstant deadline, TAutoPtr<IEventHandle> event, ISchedulerCookie* cookie)
- : Deadline(deadline)
- , Event(event)
- , Cookie(new TSchedulerCookieHolder(cookie))
- , UniqueId(++NextUniqueId)
- {}
-
- bool operator<(const TScheduledEventQueueItem& other) const {
- if (Deadline < other.Deadline)
- return true;
-
- if (Deadline > other.Deadline)
- return false;
-
- return UniqueId < other.UniqueId;
- }
-
- static ui64 NextUniqueId;
- };
-
- typedef TDeque<TAutoPtr<IEventHandle>> TEventsList;
- typedef TSet<TScheduledEventQueueItem> TScheduledEventsList;
-
- class TEventMailBox : public TThrRefBase {
- public:
- TEventMailBox()
- : InactiveUntil(TInstant::MicroSeconds(0))
-#ifdef DEBUG_ORDER_EVENTS
- , ExpectedReceive(0)
- , NextToSend(0)
-#endif
- {
- }
-
- void Send(TAutoPtr<IEventHandle> ev);
- bool IsEmpty() const;
- TAutoPtr<IEventHandle> Pop();
- void Capture(TEventsList& evList);
- void PushFront(TAutoPtr<IEventHandle>& ev);
- void PushFront(TEventsList& evList);
- void CaptureScheduled(TScheduledEventsList& evList);
- void PushScheduled(TScheduledEventsList& evList);
- bool IsActive(const TInstant& currentTime) const;
- void Freeze(const TInstant& deadline);
- TInstant GetInactiveUntil() const;
- void Schedule(const TScheduledEventQueueItem& item);
- bool IsScheduledEmpty() const;
- TInstant GetFirstScheduleDeadline() const;
- ui64 GetSentEventCount() const;
-
- private:
- TScheduledEventsList Scheduled;
- TInstant InactiveUntil;
- TEventsList Sent;
-#ifdef DEBUG_ORDER_EVENTS
- TMap<IEventHandle*, ui64> TrackSent;
- ui64 ExpectedReceive;
- ui64 NextToSend;
-#endif
- };
-
- typedef THashMap<TEventMailboxId, TIntrusivePtr<TEventMailBox>, TEventMailboxId::THash> TEventMailBoxList;
-
- class TEmptyEventQueueException : public yexception {
- public:
- TEmptyEventQueueException() {
- Append("Event queue is still empty.");
- }
- };
-
- class TSchedulingLimitReachedException : public yexception {
- public:
- TSchedulingLimitReachedException(ui64 limit) {
- TStringStream str;
- str << "TestActorRuntime Processed over " << limit << " events.";
- Append(str.Str());
- }
- };
-
- class TTestActorRuntimeBase: public TNonCopyable {
- public:
- class TEdgeActor;
- class TSchedulerThreadStub;
- class TExecutorPoolStub;
- class TTimeProvider;
- class TMonotonicTimeProvider;
-
- enum class EEventAction {
- PROCESS,
- DROP,
- RESCHEDULE
- };
-
- typedef std::function<EEventAction(TAutoPtr<IEventHandle>& event)> TEventObserver;
- typedef std::function<void(TTestActorRuntimeBase& runtime, TScheduledEventsList& scheduledEvents, TEventsList& queue)> TScheduledEventsSelector;
- typedef std::function<bool(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event)> TEventFilter;
- typedef std::function<bool(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event, TDuration delay, TInstant& deadline)> TScheduledEventFilter;
- typedef std::function<void(TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId)> TRegistrationObserver;
-
-
- TTestActorRuntimeBase(THeSingleSystemEnv);
- TTestActorRuntimeBase(ui32 nodeCount, ui32 dataCenterCount, bool UseRealThreads);
- TTestActorRuntimeBase(ui32 nodeCount, ui32 dataCenterCount);
- TTestActorRuntimeBase(ui32 nodeCount = 1, bool useRealThreads = false);
- virtual ~TTestActorRuntimeBase();
- bool IsRealThreads() const;
- static EEventAction DefaultObserverFunc(TAutoPtr<IEventHandle>& event);
- static void DroppingScheduledEventsSelector(TTestActorRuntimeBase& runtime, TScheduledEventsList& scheduledEvents, TEventsList& queue);
- static void CollapsedTimeScheduledEventsSelector(TTestActorRuntimeBase& runtime, TScheduledEventsList& scheduledEvents, TEventsList& queue);
- static bool DefaultFilterFunc(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event);
- static bool NopFilterFunc(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event, TDuration delay, TInstant& deadline);
- static void DefaultRegistrationObserver(TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId);
- TEventObserver SetObserverFunc(TEventObserver observerFunc); // deprecated, use AddObserver
- TScheduledEventsSelector SetScheduledEventsSelectorFunc(TScheduledEventsSelector scheduledEventsSelectorFunc);
- TEventFilter SetEventFilter(TEventFilter filterFunc);
- TScheduledEventFilter SetScheduledEventFilter(TScheduledEventFilter filterFunc);
- TRegistrationObserver SetRegistrationObserverFunc(TRegistrationObserver observerFunc);
- static bool IsVerbose();
- static void SetVerbose(bool verbose);
- TDuration SetDispatchTimeout(TDuration timeout);
- void SetDispatchedEventsLimit(ui64 limit) {
- DispatchedEventsLimit = limit;
- }
- TDuration SetReschedulingDelay(TDuration delay);
- void SetLogBackend(const TAutoPtr<TLogBackend> logBackend);
- void SetLogPriority(NActors::NLog::EComponent component, NActors::NLog::EPriority priority);
- TIntrusivePtr<ITimeProvider> GetTimeProvider();
- TIntrusivePtr<IMonotonicTimeProvider> GetMonotonicTimeProvider();
- TInstant GetCurrentTime() const;
- TMonotonic GetCurrentMonotonicTime() const;
- void UpdateCurrentTime(TInstant newTime);
- void AdvanceCurrentTime(TDuration duration);
- void AddLocalService(const TActorId& actorId, TActorSetupCmd cmd, ui32 nodeIndex = 0);
- virtual void Initialize();
- ui32 GetNodeId(ui32 index = 0) const;
- ui32 GetNodeCount() const;
- ui64 AllocateLocalId();
- ui32 InterconnectPoolId() const;
- TString GetTempDir();
- TActorId Register(IActor* actor, ui32 nodeIndex = 0, ui32 poolId = 0,
- TMailboxType::EType mailboxType = TMailboxType::Simple, ui64 revolvingCounter = 0,
- const TActorId& parentid = TActorId());
- TActorId Register(IActor *actor, ui32 nodeIndex, ui32 poolId, TMailboxHeader *mailbox, ui32 hint,
- const TActorId& parentid = TActorId());
- TActorId RegisterService(const TActorId& serviceId, const TActorId& actorId, ui32 nodeIndex = 0);
- TActorId AllocateEdgeActor(ui32 nodeIndex = 0);
- TEventsList CaptureEvents();
- TEventsList CaptureMailboxEvents(ui32 hint, ui32 nodeId);
- TScheduledEventsList CaptureScheduledEvents();
- void PushFront(TAutoPtr<IEventHandle>& ev);
- void PushEventsFront(TEventsList& events);
- void PushMailboxEventsFront(ui32 hint, ui32 nodeId, TEventsList& events);
- // doesn't dispatch events for edge actors
- bool DispatchEvents(const TDispatchOptions& options = TDispatchOptions());
- bool DispatchEvents(const TDispatchOptions& options, TDuration simTimeout);
- bool DispatchEvents(const TDispatchOptions& options, TInstant simDeadline);
- void Send(const TActorId& recipient, const TActorId& sender, TAutoPtr<IEventBase> ev, ui32 senderNodeIndex = 0, bool viaActorSystem = false);
- void Send(TAutoPtr<IEventHandle> ev, ui32 senderNodeIndex = 0, bool viaActorSystem = false);
- void SendAsync(TAutoPtr<IEventHandle> ev, ui32 senderNodeIndex = 0);
- void Schedule(TAutoPtr<IEventHandle> ev, const TDuration& duration, ui32 nodeIndex = 0);
- void ClearCounters();
- ui64 GetCounter(ui32 evType) const;
- TActorId GetLocalServiceId(const TActorId& serviceId, ui32 nodeIndex = 0);
- void WaitForEdgeEvents(TEventFilter filter, const TSet<TActorId>& edgeFilter = {}, TDuration simTimeout = TDuration::Max());
- TActorId GetInterconnectProxy(ui32 nodeIndexFrom, ui32 nodeIndexTo);
- void BlockOutputForActor(const TActorId& actorId);
- IActor* FindActor(const TActorId& actorId, ui32 nodeIndex = Max<ui32>()) const;
- void EnableScheduleForActor(const TActorId& actorId, bool allow = true);
- bool IsScheduleForActorEnabled(const TActorId& actorId) const;
- TIntrusivePtr<NMonitoring::TDynamicCounters> GetDynamicCounters(ui32 nodeIndex = 0);
- void SetupMonitoring();
-
- using TEventObserverCollection = std::list<std::function<void(TAutoPtr<IEventHandle>& event)>>;
- class TEventObserverHolder {
- public:
- TEventObserverHolder(TEventObserverCollection& list, TEventObserverCollection::iterator&& iter)
- : List(list)
- , Iter(iter)
- {
- }
-
- ~TEventObserverHolder()
- {
- Remove();
- }
-
- void Remove()
- {
- if (Iter == List.end()) {
- return;
- }
-
- List.erase(Iter);
- Iter = List.end();
- }
- private:
- TEventObserverCollection& List;
- TEventObserverCollection::iterator Iter;
- };
-
- // An example of using AddObserver in unit tests
- /*
- auto observerHolder = runtime.AddObserver<TEvDataShard::TEvRead>([&](TEvDataShard::TEvRead::TPtr& event) {
- // Do something with the event inside the calback
- Cout << "An event is observed " << ev->Get()->Record.ShortDebugString() << Endl;
-
- // Optionally reset the event, all subsequent handlers of this event will not be called
- event.Reset();
- });
-
- // Do something inside the main code of the unit test
-
- // Optionally remove the observer, otherwise it will be destroyed in its destructor
- observerHolder.Remove();
- */
-
- template <typename TEvType>
- TEventObserverHolder AddObserver(std::function<void(typename TEvType::TPtr&)> observerFunc)
- {
- auto baseFunc = [observerFunc](TAutoPtr<IEventHandle>& event) {
- if (event && event->GetTypeRewrite() == TEvType::EventType)
- observerFunc(*(reinterpret_cast<typename TEvType::TPtr*>(&event)));
- };
-
- auto iter = ObserverFuncs.insert(ObserverFuncs.end(), baseFunc);
- return TEventObserverHolder(ObserverFuncs, std::move(iter));
- }
-
- TEventObserverHolder AddObserver(std::function<void(TAutoPtr<IEventHandle>&)> observerFunc)
- {
- auto iter = ObserverFuncs.insert(ObserverFuncs.end(), observerFunc);
- return TEventObserverHolder(ObserverFuncs, std::move(iter));
- }
-
- template<typename T>
- void AppendToLogSettings(NLog::EComponent minVal, NLog::EComponent maxVal, T func) {
- Y_ABORT_UNLESS(!IsInitialized);
-
- for (const auto& pair : Nodes) {
- pair.second->LogSettings->Append(minVal, maxVal, func);
- }
- }
-
- TIntrusivePtr<NLog::TSettings> GetLogSettings(ui32 nodeIdx)
- {
- return Nodes[FirstNodeId + nodeIdx]->LogSettings;
- }
-
- TActorSystem* SingleSys() const;
- TActorSystem* GetAnyNodeActorSystem();
- TActorSystem* GetActorSystem(ui32 nodeId);
- template <typename TEvent>
- TEvent* GrabEdgeEventIf(TAutoPtr<IEventHandle>& handle, std::function<bool(const TEvent&)> predicate, TDuration simTimeout = TDuration::Max()) {
- handle.Destroy();
- const ui32 eventType = TEvent::EventType;
- WaitForEdgeEvents([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
- Y_UNUSED(runtime);
- if (event->GetTypeRewrite() != eventType)
- return false;
-
- TEvent* typedEvent = event->Get<TEvent>();
- if (predicate(*typedEvent)) {
- handle = event;
- return true;
- }
-
- return false;
- }, {}, simTimeout);
-
- if (simTimeout == TDuration::Max())
- Y_ABORT_UNLESS(handle);
-
- if (handle) {
- return handle->Get<TEvent>();
- } else {
- return nullptr;
- }
- }
-
- template<class TEvent>
- typename TEvent::TPtr GrabEdgeEventIf(
- const TSet<TActorId>& edgeFilter,
- const std::function<bool(const typename TEvent::TPtr&)>& predicate,
- TDuration simTimeout = TDuration::Max())
- {
- typename TEvent::TPtr handle;
- const ui32 eventType = TEvent::EventType;
- WaitForEdgeEvents([&](TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event) {
- Y_UNUSED(runtime);
- if (event->GetTypeRewrite() != eventType)
- return false;
-
- typename TEvent::TPtr* typedEvent = reinterpret_cast<typename TEvent::TPtr*>(&event);
- if (predicate(*typedEvent)) {
- handle = *typedEvent;
- return true;
- }
-
- return false;
- }, edgeFilter, simTimeout);
-
- if (simTimeout == TDuration::Max())
- Y_ABORT_UNLESS(handle);
-
- return handle;
- }
-
- template<class TEvent>
- typename TEvent::TPtr GrabEdgeEventIf(
- const TActorId& edgeActor,
- const std::function<bool(const typename TEvent::TPtr&)>& predicate,
- TDuration simTimeout = TDuration::Max())
- {
- TSet<TActorId> edgeFilter{edgeActor};
- return GrabEdgeEventIf<TEvent>(edgeFilter, predicate, simTimeout);
- }
-
- template <typename TEvent>
- TEvent* GrabEdgeEvent(TAutoPtr<IEventHandle>& handle, TDuration simTimeout = TDuration::Max()) {
- std::function<bool(const TEvent&)> truth = [](const TEvent&) { return true; };
- return GrabEdgeEventIf(handle, truth, simTimeout);
- }
-
- template <typename TEvent>
- THolder<TEvent> GrabEdgeEvent(TDuration simTimeout = TDuration::Max()) {
- TAutoPtr<IEventHandle> handle;
- std::function<bool(const TEvent&)> truth = [](const TEvent&) { return true; };
- GrabEdgeEventIf(handle, truth, simTimeout);
- if (handle) {
- return THolder<TEvent>(handle->Release<TEvent>());
- }
- return {};
- }
-
- template<class TEvent>
- typename TEvent::TPtr GrabEdgeEvent(const TSet<TActorId>& edgeFilter, TDuration simTimeout = TDuration::Max()) {
- return GrabEdgeEventIf<TEvent>(edgeFilter, [](const typename TEvent::TPtr&) { return true; }, simTimeout);
- }
-
- template<class TEvent>
- typename TEvent::TPtr GrabEdgeEvent(const TActorId& edgeActor, TDuration simTimeout = TDuration::Max()) {
- TSet<TActorId> edgeFilter{edgeActor};
- return GrabEdgeEvent<TEvent>(edgeFilter, simTimeout);
- }
-
- // replace with std::variant<>
- template <typename... TEvents>
- std::tuple<TEvents*...> GrabEdgeEvents(TAutoPtr<IEventHandle>& handle, TDuration simTimeout = TDuration::Max()) {
- handle.Destroy();
- auto eventTypes = { TEvents::EventType... };
- WaitForEdgeEvents([&](TTestActorRuntimeBase&, TAutoPtr<IEventHandle>& event) {
- if (std::find(std::begin(eventTypes), std::end(eventTypes), event->GetTypeRewrite()) == std::end(eventTypes))
- return false;
- handle = event;
- return true;
- }, {}, simTimeout);
- if (simTimeout == TDuration::Max())
- Y_ABORT_UNLESS(handle);
- if (handle) {
- return std::make_tuple(handle->Type == TEvents::EventType
- ? handle->Get<TEvents>()
- : static_cast<TEvents*>(nullptr)...);
- }
- return {};
- }
-
- template <typename TEvent>
- TEvent* GrabEdgeEventRethrow(TAutoPtr<IEventHandle>& handle, TDuration simTimeout = TDuration::Max()) {
- try {
- return GrabEdgeEvent<TEvent>(handle, simTimeout);
- } catch (...) {
- ythrow TWithBackTrace<yexception>() << "Exception occured while waiting for " << TypeName<TEvent>() << ": " << CurrentExceptionMessage();
- }
- }
-
- template<class TEvent>
- typename TEvent::TPtr GrabEdgeEventRethrow(const TSet<TActorId>& edgeFilter, TDuration simTimeout = TDuration::Max()) {
- try {
- return GrabEdgeEvent<TEvent>(edgeFilter, simTimeout);
- } catch (...) {
- ythrow TWithBackTrace<yexception>() << "Exception occured while waiting for " << TypeName<TEvent>() << ": " << CurrentExceptionMessage();
- }
- }
-
- template<class TEvent>
- typename TEvent::TPtr GrabEdgeEventRethrow(const TActorId& edgeActor, TDuration simTimeout = TDuration::Max()) {
- try {
- return GrabEdgeEvent<TEvent>(edgeActor, simTimeout);
- } catch (...) {
- ythrow TWithBackTrace<yexception>() << "Exception occured while waiting for " << TypeName<TEvent>() << ": " << CurrentExceptionMessage();
- }
- }
-
- template <typename... TEvents>
- static TString TypeNames() {
- static TString names[] = { TypeName<TEvents>()... };
- TString result;
- for (const TString& s : names) {
- if (result.empty()) {
- result += '<';
- } else {
- result += ',';
- }
- result += s;
- }
- if (!result.empty()) {
- result += '>';
- }
- return result;
- }
-
- template <typename... TEvents>
- std::tuple<TEvents*...> GrabEdgeEventsRethrow(TAutoPtr<IEventHandle>& handle, TDuration simTimeout = TDuration::Max()) {
- try {
- return GrabEdgeEvents<TEvents...>(handle, simTimeout);
- } catch (...) {
- ythrow TWithBackTrace<yexception>() << "Exception occured while waiting for " << TypeNames<TEvents...>() << ": " << CurrentExceptionMessage();
- }
- }
-
- void ResetScheduledCount() {
- ScheduledCount = 0;
- }
-
- void SetScheduledLimit(ui64 limit) {
- ScheduledLimit = limit;
- }
-
- void SetDispatcherRandomSeed(TInstant time, ui64 iteration);
- TString GetActorName(const TActorId& actorId) const;
-
- const TVector<ui64>& GetTxAllocatorTabletIds() const { return TxAllocatorTabletIds; }
- void SetTxAllocatorTabletIds(const TVector<ui64>& ids) { TxAllocatorTabletIds = ids; }
-
- void SetUseRealInterconnect() {
- UseRealInterconnect = true;
- }
-
- void SetICCommonSetupper(std::function<void(ui32, TIntrusivePtr<TInterconnectProxyCommon>)>&& icCommonSetupper) {
- ICCommonSetupper = std::move(icCommonSetupper);
- }
-
- protected:
- struct TNodeDataBase;
- TNodeDataBase* GetRawNode(ui32 node) const {
- return Nodes.at(FirstNodeId + node).Get();
- }
-
- static IExecutorPool* CreateExecutorPoolStub(TTestActorRuntimeBase* runtime, ui32 nodeIndex, TNodeDataBase* node, ui32 poolId);
- virtual TIntrusivePtr<NMonitoring::TDynamicCounters> GetCountersForComponent(TIntrusivePtr<NMonitoring::TDynamicCounters> counters, const char* component) {
- Y_UNUSED(counters);
- Y_UNUSED(component);
-
- // do nothing, just return the existing counters
- return counters;
- }
-
- THolder<TActorSystemSetup> MakeActorSystemSetup(ui32 nodeIndex, TNodeDataBase* node);
- THolder<TActorSystem> MakeActorSystem(ui32 nodeIndex, TNodeDataBase* node);
- virtual void InitActorSystemSetup(TActorSystemSetup& setup) {
- Y_UNUSED(setup);
- }
-
- private:
- IActor* FindActor(const TActorId& actorId, TNodeDataBase* node) const;
- void SendInternal(TAutoPtr<IEventHandle> ev, ui32 nodeIndex, bool viaActorSystem);
- TEventMailBox& GetMailbox(ui32 nodeId, ui32 hint);
- void ClearMailbox(ui32 nodeId, ui32 hint);
- void HandleNonEmptyMailboxesForEachContext(TEventMailboxId mboxId);
- void UpdateFinalEventsStatsForEachContext(IEventHandle& ev);
- bool DispatchEventsInternal(const TDispatchOptions& options, TInstant simDeadline);
-
- private:
- ui64 ScheduledCount;
- ui64 ScheduledLimit;
- THolder<TTempDir> TmpDir;
- const TThread::TId MainThreadId;
-
- protected:
- bool UseRealInterconnect = false;
- TInterconnectMock InterconnectMock;
- bool IsInitialized = false;
- bool SingleSysEnv = false;
- const TString ClusterUUID;
- const ui32 FirstNodeId;
- const ui32 NodeCount;
- const ui32 DataCenterCount;
- const bool UseRealThreads;
- std::function<void(ui32, TIntrusivePtr<TInterconnectProxyCommon>)> ICCommonSetupper;
-
- ui64 LocalId;
- TMutex Mutex;
- TCondVar MailboxesHasEvents;
- TEventMailBoxList Mailboxes;
- TMap<ui32, ui64> EvCounters;
- ui64 DispatchCyclesCount;
- ui64 DispatchedEventsCount;
- ui64 DispatchedEventsLimit = 2'500'000;
- TActorId CurrentRecipient;
- ui64 DispatcherRandomSeed;
- TIntrusivePtr<IRandomProvider> DispatcherRandomProvider;
- TAutoPtr<TLogBackend> LogBackend;
- bool NeedMonitoring;
-
- TIntrusivePtr<IRandomProvider> RandomProvider;
- TIntrusivePtr<ITimeProvider> TimeProvider;
- TIntrusivePtr<IMonotonicTimeProvider> MonotonicTimeProvider;
-
- protected:
- struct TNodeDataBase: public TThrRefBase {
- TNodeDataBase();
- void Stop();
- virtual ~TNodeDataBase();
- virtual ui64 GetLoggerPoolId() const {
- return 0;
- }
-
- template <typename T = void>
- T* GetAppData() {
- return static_cast<T*>(AppData0.get());
- }
-
- template <typename T = void>
- const T* GetAppData() const {
- return static_cast<T*>(AppData0.get());
- }
-
- TIntrusivePtr<NMonitoring::TDynamicCounters> DynamicCounters;
- TIntrusivePtr<NActors::NLog::TSettings> LogSettings;
- TIntrusivePtr<NInterconnect::TPollerThreads> Poller;
- volatile ui64* ActorSystemTimestamp;
- volatile ui64* ActorSystemMonotonic;
- TVector<std::pair<TActorId, TTestActorSetupCmd>> LocalServices;
- TMap<TActorId, IActor*> LocalServicesActors;
- TMap<IActor*, TActorId> ActorToActorId;
- THolder<TMailboxTable> MailboxTable;
- std::shared_ptr<void> AppData0;
- THolder<TActorSystem> ActorSystem;
- THolder<IExecutorPool> SchedulerPool;
- TVector<IExecutorPool*> ExecutorPools;
- THolder<TExecutorThread> ExecutorThread;
- };
-
- struct INodeFactory {
- virtual ~INodeFactory() = default;
- virtual TIntrusivePtr<TNodeDataBase> CreateNode() = 0;
- };
-
- struct TDefaultNodeFactory final: INodeFactory {
- virtual TIntrusivePtr<TNodeDataBase> CreateNode() override {
- return new TNodeDataBase();
- }
- };
-
- INodeFactory& GetNodeFactory() {
- return *NodeFactory;
- }
-
- virtual TNodeDataBase* GetNodeById(size_t idx) {
- return Nodes[idx].Get();
- }
-
- void InitNodes();
- void CleanupNodes();
- virtual void InitNodeImpl(TNodeDataBase*, size_t);
-
- static bool AllowSendFrom(TNodeDataBase* node, TAutoPtr<IEventHandle>& ev);
-
- protected:
- THolder<INodeFactory> NodeFactory{new TDefaultNodeFactory};
-
- private:
- void InitNode(TNodeDataBase* node, size_t idx);
-
- struct TDispatchContext {
- const TDispatchOptions* Options;
- TDispatchContext* PrevContext;
-
- TMap<const TDispatchOptions::TFinalEventCondition*, ui32> FinalEventFrequency;
- TSet<TEventMailboxId> FoundNonEmptyMailboxes;
- bool FinalEventFound = false;
- };
-
- TProgramShouldContinue ShouldContinue;
- TMap<ui32, TIntrusivePtr<TNodeDataBase>> Nodes;
- ui64 CurrentTimestamp;
- TSet<TActorId> EdgeActors;
- THashMap<TEventMailboxId, TActorId, TEventMailboxId::THash> EdgeActorByMailbox;
- TDuration DispatchTimeout;
- TDuration ReschedulingDelay;
- TEventObserver ObserverFunc;
- TEventObserverCollection ObserverFuncs;
- TScheduledEventsSelector ScheduledEventsSelectorFunc;
- TEventFilter EventFilterFunc;
- TScheduledEventFilter ScheduledEventFilterFunc;
- TRegistrationObserver RegistrationObserver;
- TSet<TActorId> BlockedOutput;
- TSet<TActorId> ScheduleWhiteList;
- THashMap<TActorId, TActorId> ScheduleWhiteListParent;
- THashMap<TActorId, TString> ActorNames;
- TDispatchContext* CurrentDispatchContext;
- TVector<ui64> TxAllocatorTabletIds;
-
- static ui32 NextNodeId;
- };
-
- template <typename TEvent>
- TEvent* FindEvent(TEventsList& events) {
- for (auto& event : events) {
- if (event && event->GetTypeRewrite() == TEvent::EventType) {
- return event->CastAsLocal<TEvent>();
- }
- }
-
- return nullptr;
- }
-
- template <typename TEvent>
- TEvent* FindEvent(TEventsList& events, const std::function<bool(const TEvent&)>& predicate) {
- for (auto& event : events) {
- if (event && event->GetTypeRewrite() == TEvent::EventType && predicate(*event->CastAsLocal<TEvent>())) {
- return event->CastAsLocal<TEvent>();
- }
- }
-
- return nullptr;
- }
-
- template <typename TEvent>
- TEvent* GrabEvent(TEventsList& events, TAutoPtr<IEventHandle>& ev) {
- ev.Destroy();
- for (auto& event : events) {
- if (event && event->GetTypeRewrite() == TEvent::EventType) {
- ev = event;
- return ev->CastAsLocal<TEvent>();
- }
- }
-
- return nullptr;
- }
-
- template <typename TEvent>
- TEvent* GrabEvent(TEventsList& events, TAutoPtr<IEventHandle>& ev,
- const std::function<bool(const typename TEvent::TPtr&)>& predicate) {
- ev.Destroy();
- for (auto& event : events) {
- if (event && event->GetTypeRewrite() == TEvent::EventType) {
- if (predicate(reinterpret_cast<const typename TEvent::TPtr&>(event))) {
- ev = event;
- return ev->CastAsLocal<TEvent>();
- }
- }
- }
-
- return nullptr;
- }
-
- class IStrandingDecoratorFactory {
- public:
- virtual ~IStrandingDecoratorFactory() {}
- virtual IActor* Wrap(const TActorId& delegatee, bool isSync, const TVector<TActorId>& additionalActors) = 0;
- };
-
- struct IReplyChecker {
- virtual ~IReplyChecker() {}
- virtual void OnRequest(IEventHandle *request) = 0;
- virtual bool IsWaitingForMoreResponses(IEventHandle *response) = 0;
- };
-
- struct TNoneReplyChecker : IReplyChecker {
- void OnRequest(IEventHandle*) override {
- }
-
- bool IsWaitingForMoreResponses(IEventHandle*) override {
- return false;
- }
- };
-
- using TReplyCheckerCreator = std::function<THolder<IReplyChecker>(void)>;
-
- inline THolder<IReplyChecker> CreateNoneReplyChecker() {
- return MakeHolder<TNoneReplyChecker>();
- }
-
- TAutoPtr<IStrandingDecoratorFactory> CreateStrandingDecoratorFactory(TTestActorRuntimeBase* runtime,
- TReplyCheckerCreator createReplyChecker = CreateNoneReplyChecker);
- extern ui64 DefaultRandomSeed;
-}
diff --git a/library/cpp/actors/testlib/ut/CMakeLists.darwin-arm64.txt b/library/cpp/actors/testlib/ut/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index ae1df12ed6..0000000000
--- a/library/cpp/actors/testlib/ut/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-testlib-ut)
-target_include_directories(library-cpp-actors-testlib-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib
-)
-target_link_libraries(library-cpp-actors-testlib-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-testlib
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-testlib-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-testlib-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib/decorator_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-testlib-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-testlib-ut
- TEST_TARGET
- library-cpp-actors-testlib-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-testlib-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-testlib-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-testlib-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-testlib-ut)
diff --git a/library/cpp/actors/testlib/ut/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/testlib/ut/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 03d106c63f..0000000000
--- a/library/cpp/actors/testlib/ut/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-testlib-ut)
-target_include_directories(library-cpp-actors-testlib-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib
-)
-target_link_libraries(library-cpp-actors-testlib-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-testlib
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-testlib-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-testlib-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib/decorator_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-testlib-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-testlib-ut
- TEST_TARGET
- library-cpp-actors-testlib-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-testlib-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-testlib-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-testlib-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-testlib-ut)
diff --git a/library/cpp/actors/testlib/ut/CMakeLists.linux-aarch64.txt b/library/cpp/actors/testlib/ut/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 598b6e53de..0000000000
--- a/library/cpp/actors/testlib/ut/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-testlib-ut)
-target_include_directories(library-cpp-actors-testlib-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib
-)
-target_link_libraries(library-cpp-actors-testlib-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-testlib
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-testlib-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-testlib-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib/decorator_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-testlib-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-testlib-ut
- TEST_TARGET
- library-cpp-actors-testlib-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-testlib-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-testlib-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-testlib-ut
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-testlib-ut)
diff --git a/library/cpp/actors/testlib/ut/CMakeLists.linux-x86_64.txt b/library/cpp/actors/testlib/ut/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 42713842da..0000000000
--- a/library/cpp/actors/testlib/ut/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-testlib-ut)
-target_include_directories(library-cpp-actors-testlib-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib
-)
-target_link_libraries(library-cpp-actors-testlib-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-testlib
- cpp-actors-core
-)
-target_link_options(library-cpp-actors-testlib-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-testlib-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib/decorator_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-testlib-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-testlib-ut
- TEST_TARGET
- library-cpp-actors-testlib-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-testlib-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-testlib-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-testlib-ut
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-testlib-ut)
diff --git a/library/cpp/actors/testlib/ut/CMakeLists.txt b/library/cpp/actors/testlib/ut/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/testlib/ut/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/testlib/ut/CMakeLists.windows-x86_64.txt b/library/cpp/actors/testlib/ut/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 077ccae7fb..0000000000
--- a/library/cpp/actors/testlib/ut/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-testlib-ut)
-target_include_directories(library-cpp-actors-testlib-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib
-)
-target_link_libraries(library-cpp-actors-testlib-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-testlib
- cpp-actors-core
-)
-target_sources(library-cpp-actors-testlib-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/testlib/decorator_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-testlib-ut
- PROPERTY
- SPLIT_FACTOR
- 10
-)
-add_yunittest(
- NAME
- library-cpp-actors-testlib-ut
- TEST_TARGET
- library-cpp-actors-testlib-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-testlib-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-testlib-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-testlib-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-testlib-ut)
diff --git a/library/cpp/actors/testlib/ut/ya.make b/library/cpp/actors/testlib/ut/ya.make
deleted file mode 100644
index ea6aef37a6..0000000000
--- a/library/cpp/actors/testlib/ut/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-UNITTEST_FOR(library/cpp/actors/testlib)
-
-FORK_SUBTESTS()
-SIZE(SMALL)
-
-
-PEERDIR(
- library/cpp/actors/core
-)
-
-SRCS(
- decorator_ut.cpp
-)
-
-END()
diff --git a/library/cpp/actors/testlib/ya.make b/library/cpp/actors/testlib/ya.make
deleted file mode 100644
index 0bd44ddd57..0000000000
--- a/library/cpp/actors/testlib/ya.make
+++ /dev/null
@@ -1,23 +0,0 @@
-LIBRARY()
-
-SRCS(
- test_runtime.cpp
-)
-
-PEERDIR(
- library/cpp/actors/core
- library/cpp/actors/interconnect/mock
- library/cpp/actors/protos
- library/cpp/random_provider
- library/cpp/time_provider
-)
-
-IF (GCC)
- CFLAGS(-fno-devirtualize-speculatively)
-ENDIF()
-
-END()
-
-RECURSE_FOR_TESTS(
- ut
-)
diff --git a/library/cpp/actors/util/CMakeLists.darwin-arm64.txt b/library/cpp/actors/util/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index be68d418f7..0000000000
--- a/library/cpp/actors/util/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-util)
-target_link_libraries(cpp-actors-util PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-containers-absl_flat_hash
- cpp-deprecated-atomic
- library-cpp-pop_count
-)
-target_sources(cpp-actors-util PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/affinity.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_track.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_tracker.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rope.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rc_buf.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/should_continue.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/threadparkpad.cpp
-)
diff --git a/library/cpp/actors/util/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/util/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index be68d418f7..0000000000
--- a/library/cpp/actors/util/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-util)
-target_link_libraries(cpp-actors-util PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-containers-absl_flat_hash
- cpp-deprecated-atomic
- library-cpp-pop_count
-)
-target_sources(cpp-actors-util PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/affinity.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_track.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_tracker.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rope.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rc_buf.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/should_continue.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/threadparkpad.cpp
-)
diff --git a/library/cpp/actors/util/CMakeLists.linux-aarch64.txt b/library/cpp/actors/util/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 9c5183c2bd..0000000000
--- a/library/cpp/actors/util/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-util)
-target_link_libraries(cpp-actors-util PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-containers-absl_flat_hash
- cpp-deprecated-atomic
- library-cpp-pop_count
-)
-target_sources(cpp-actors-util PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/affinity.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_track.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_tracker.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rope.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rc_buf.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/should_continue.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/threadparkpad.cpp
-)
diff --git a/library/cpp/actors/util/CMakeLists.linux-x86_64.txt b/library/cpp/actors/util/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 9c5183c2bd..0000000000
--- a/library/cpp/actors/util/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-util)
-target_link_libraries(cpp-actors-util PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-containers-absl_flat_hash
- cpp-deprecated-atomic
- library-cpp-pop_count
-)
-target_sources(cpp-actors-util PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/affinity.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_track.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_tracker.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rope.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rc_buf.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/should_continue.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/threadparkpad.cpp
-)
diff --git a/library/cpp/actors/util/CMakeLists.txt b/library/cpp/actors/util/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/util/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/util/CMakeLists.windows-x86_64.txt b/library/cpp/actors/util/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index be68d418f7..0000000000
--- a/library/cpp/actors/util/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(ut)
-
-add_library(cpp-actors-util)
-target_link_libraries(cpp-actors-util PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-containers-absl_flat_hash
- cpp-deprecated-atomic
- library-cpp-pop_count
-)
-target_sources(cpp-actors-util PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/affinity.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_track.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_tracker.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rope.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rc_buf.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/should_continue.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/threadparkpad.cpp
-)
diff --git a/library/cpp/actors/util/README.md b/library/cpp/actors/util/README.md
deleted file mode 100644
index ff2d573fe8..0000000000
--- a/library/cpp/actors/util/README.md
+++ /dev/null
@@ -1,99 +0,0 @@
-## Memory tracker
-
-https://a.yandex-team.ru/arc/trunk/arcadia/library/cpp/actors/util/memory_track.h
-
-Использование:
-
-* отслеживание аллокаций экземпляров конкретного класса через new/delete и new[]/delete[]
-* отслеживание аллокаций в контейнерах
-* ручное отслеживание моментов аллокации/деаллокации
-
-----
-
-### Отслеживание аллокаций класса через new/delete
-
-Использование с автоматически генерируемой меткой:
-
-```cpp
-#include <library/cpp/actors/util/memory_track.h>
-
-struct TTypeLabeled
- : public NActors::NMemory::TTrack<TTypeLabeled>
-{
- char payload[16];
-};
-```
-
-Использование с пользовательским именем метки:
-
-```cpp
-#include <library/cpp/actors/util/memory_track.h>
-
-static const char NamedLabel[] = "NamedLabel";
-
-struct TNameLabeled
- : public NActors::NMemory::TTrack<TNameLabeled, NamedLabel>
-{
- char payload[32];
-};
-```
-
-----
-
-### Отслеживание аллокаций в контейнерах
-
-```cpp
-#include <library/cpp/actors/util/memory_track.h>
-
-static const char InContainerLabel[] = "InContainerLabel";
-
-struct TInContainer {
- char payload[16];
-};
-
-std::vector<TInContainer, NActors::NMemory::TAlloc<TInContainer>> vecT;
-
-std::vector<TInContainer, NActors::NMemory::TAlloc<TInContainer, InContainerLabel>> vecN;
-
-using TKey = int;
-
-std::map<TKey, TInContainer, std::less<TKey>,
- NActors::NMemory::TAlloc<std::pair<const TKey, TInContainer>>> mapT;
-
-std::map<TKey, TInContainer, std::less<TKey>,
- NActors::NMemory::TAlloc<std::pair<const TKey, TInContainer>, InContainerLabel>> mapN;
-
-std::unordered_map<TKey, TInContainer, std::hash<TKey>, std::equal_to<TKey>,
- NActors::NMemory::TAlloc<std::pair<const TKey, TInContainer>>> umapT;
-
-std::unordered_map<TKey, TInContainer, std::hash<TKey>, std::equal_to<TKey>,
- NActors::NMemory::TAlloc<std::pair<const TKey, TInContainer>, InContainerLabel>> umapN;
-```
-
-----
-
-### Ручное отслеживание аллокаций/деаллокаций
-
-```cpp
-#include <library/cpp/actors/util/memory_track.h>
-
-static const char ManualLabel[] = "ManualLabel";
-
-...
-NActors::NMemory::TLabel<ManualLabel>::Add(size);
-
-...
-NActors::NMemory::TLabel<ManualLabel>::Sub(size);
-```
-
-----
-
-### Собираемые метрики
-
-Сервис **utils**, пользовательская метка **label**, сенсоры:
-
-- MT/Count: количество аллокаций в моменте
-- MT/Memory: аллоцированная память в моменте
-- MT/PeakCount: пиковое значение количества аллокаций (сэмплится с фиксированной частотой)
-- MT/PeakMemory: пиковое значение аллоцированной памяти
-
diff --git a/library/cpp/actors/util/affinity.cpp b/library/cpp/actors/util/affinity.cpp
deleted file mode 100644
index 5851105ae7..0000000000
--- a/library/cpp/actors/util/affinity.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "affinity.h"
-
-#ifdef _linux_
-#include <sched.h>
-#endif
-
-class TAffinity::TImpl {
-#ifdef _linux_
- cpu_set_t Mask;
-#endif
-public:
- TImpl() {
-#ifdef _linux_
- int ar = sched_getaffinity(0, sizeof(cpu_set_t), &Mask);
- Y_DEBUG_ABORT_UNLESS(ar == 0);
-#endif
- }
-
- explicit TImpl(const ui8* cpus, ui32 size) {
-#ifdef _linux_
- CPU_ZERO(&Mask);
- for (ui32 i = 0; i != size; ++i) {
- if (cpus[i]) {
- CPU_SET(i, &Mask);
- }
- }
-#else
- Y_UNUSED(cpus);
- Y_UNUSED(size);
-#endif
- }
-
- void Set() const {
-#ifdef _linux_
- int ar = sched_setaffinity(0, sizeof(cpu_set_t), &Mask);
- Y_DEBUG_ABORT_UNLESS(ar == 0);
-#endif
- }
-
- operator TCpuMask() const {
- TCpuMask result;
-#ifdef _linux_
- for (ui32 i = 0; i != CPU_SETSIZE; ++i) {
- result.Cpus.emplace_back(CPU_ISSET(i, &Mask));
- }
- result.RemoveTrailingZeros();
-#endif
- return result;
- }
-
-};
-
-TAffinity::TAffinity() {
-}
-
-TAffinity::~TAffinity() {
-}
-
-TAffinity::TAffinity(const ui8* x, ui32 sz) {
- if (x && sz) {
- Impl.Reset(new TImpl(x, sz));
- }
-}
-
-TAffinity::TAffinity(const TCpuMask& mask) {
- if (!mask.IsEmpty()) {
- static_assert(sizeof(ui8) == sizeof(mask.Cpus[0]));
- const ui8* x = reinterpret_cast<const ui8*>(&mask.Cpus[0]);
- const ui32 sz = mask.Size();
- Impl.Reset(new TImpl(x, sz));
- }
-}
-
-void TAffinity::Current() {
- Impl.Reset(new TImpl());
-}
-
-void TAffinity::Set() const {
- if (!!Impl) {
- Impl->Set();
- }
-}
-
-bool TAffinity::Empty() const {
- return !Impl;
-}
-
-TAffinity::operator TCpuMask() const {
- if (!!Impl) {
- return *Impl;
- }
- return TCpuMask();
-}
diff --git a/library/cpp/actors/util/affinity.h b/library/cpp/actors/util/affinity.h
deleted file mode 100644
index ae106ed180..0000000000
--- a/library/cpp/actors/util/affinity.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include "cpumask.h"
-
-// Platform-specific class to set or get thread affinity
-class TAffinity: public TThrRefBase, TNonCopyable {
- class TImpl;
- THolder<TImpl> Impl;
-
-public:
- TAffinity();
- TAffinity(const ui8* cpus, ui32 size);
- explicit TAffinity(const TCpuMask& mask);
- ~TAffinity();
-
- void Current();
- void Set() const;
- bool Empty() const;
-
- operator TCpuMask() const;
-};
-
-// Scoped affinity setter
-class TAffinityGuard : TNonCopyable {
- bool Stacked;
- TAffinity OldAffinity;
-
-public:
- TAffinityGuard(const TAffinity* affinity) {
- Stacked = false;
- if (affinity && !affinity->Empty()) {
- OldAffinity.Current();
- affinity->Set();
- Stacked = true;
- }
- }
-
- ~TAffinityGuard() {
- Release();
- }
-
- void Release() {
- if (Stacked) {
- OldAffinity.Set();
- Stacked = false;
- }
- }
-};
diff --git a/library/cpp/actors/util/cpu_load_log.h b/library/cpp/actors/util/cpu_load_log.h
deleted file mode 100644
index 225f7148da..0000000000
--- a/library/cpp/actors/util/cpu_load_log.h
+++ /dev/null
@@ -1,227 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include <library/cpp/deprecated/atomic/atomic.h>
-#include <library/cpp/pop_count/popcount.h>
-
-static constexpr ui64 BitDurationNs = 131'072; // A power of 2
-
-template <ui64 DataSize>
-struct TCpuLoadLog {
- static constexpr ui64 BitsSize = DataSize * 64;
- TAtomic LastTimeNs = 0;
- ui64 Data[DataSize];
-
- TCpuLoadLog() {
- LastTimeNs = 0;
- for (size_t i = 0; i < DataSize; ++i) {
- Data[i] = 0;
- }
- }
-
- TCpuLoadLog(ui64 timeNs) {
- LastTimeNs = timeNs;
- for (size_t i = 0; i < DataSize; ++i) {
- Data[i] = 0;
- }
- }
-
- void RegisterBusyPeriod(ui64 timeNs) {
- RegisterBusyPeriod<true>(timeNs, AtomicGet(LastTimeNs));
- }
-
- template <bool ModifyLastTime>
- void RegisterBusyPeriod(ui64 timeNs, ui64 lastTimeNs) {
- timeNs |= 1ull;
- if (timeNs < lastTimeNs) {
- for (ui64 i = 0; i < DataSize; ++i) {
- AtomicSet(Data[i], ~0ull);
- }
- if (ModifyLastTime) {
- AtomicSet(LastTimeNs, timeNs);
- }
- return;
- }
- const ui64 lastIdx = timeNs / BitDurationNs;
- const ui64 curIdx = lastTimeNs / BitDurationNs;
- ui64 firstElementIdx = curIdx / 64;
- const ui64 firstBitIdx = curIdx % 64;
- const ui64 lastElementIdx = lastIdx / 64;
- const ui64 lastBitIdx = lastIdx % 64;
- if (firstElementIdx == lastElementIdx) {
- ui64 prevValue = 0;
- if (firstBitIdx != 0) {
- prevValue = AtomicGet(Data[firstElementIdx % DataSize]);
- }
- const ui64 bits = (((~0ull) << (firstBitIdx + (63-lastBitIdx))) >> (63-lastBitIdx));
- const ui64 newValue = prevValue | bits;
- AtomicSet(Data[firstElementIdx % DataSize], newValue);
- if (ModifyLastTime) {
- AtomicSet(LastTimeNs, timeNs);
- }
- return;
- }
- // process the first element
- ui64 prevValue = 0;
- if (firstBitIdx != 0) {
- prevValue = AtomicGet(Data[firstElementIdx % DataSize]);
- }
- const ui64 bits = ((~0ull) << firstBitIdx);
- const ui64 newValue = (prevValue | bits);
- AtomicSet(Data[firstElementIdx % DataSize], newValue);
- ++firstElementIdx;
- // process the fully filled elements
- const ui64 firstLoop = firstElementIdx / DataSize;
- const ui64 lastLoop = lastElementIdx / DataSize;
- const ui64 lastOffset = lastElementIdx % DataSize;
- if (firstLoop < lastLoop) {
- for (ui64 i = firstElementIdx % DataSize; i < DataSize; ++i) {
- AtomicSet(Data[i], ~0ull);
- }
- for (ui64 i = 0; i < lastOffset; ++i) {
- AtomicSet(Data[i], ~0ull);
- }
- } else {
- for (ui64 i = firstElementIdx % DataSize; i < lastOffset; ++i) {
- AtomicSet(Data[i], ~0ull);
- }
- }
- // process the last element
- const ui64 newValue2 = ((~0ull) >> (63-lastBitIdx));
- AtomicSet(Data[lastOffset], newValue2);
- if (ModifyLastTime) {
- AtomicSet(LastTimeNs, timeNs);
- }
- }
-
- void RegisterIdlePeriod(ui64 timeNs) {
- timeNs &= ~1ull;
- ui64 lastTimeNs = AtomicGet(LastTimeNs);
- if (timeNs < lastTimeNs) {
- // Fast check first, slower chec later
- if ((timeNs | 1ull) < lastTimeNs) {
- // Time goes back, dont panic, just mark the whole array 'busy'
- for (ui64 i = 0; i < DataSize; ++i) {
- AtomicSet(Data[i], ~0ull);
- }
- AtomicSet(LastTimeNs, timeNs);
- return;
- }
- }
- const ui64 curIdx = lastTimeNs / BitDurationNs;
- const ui64 lastIdx = timeNs / BitDurationNs;
- ui64 firstElementIdx = curIdx / 64;
- const ui64 lastElementIdx = lastIdx / 64;
- if (firstElementIdx >= lastElementIdx) {
- AtomicSet(LastTimeNs, timeNs);
- return;
- }
- // process the first partially filled element
- ++firstElementIdx;
- // process all other elements
- const ui64 firstLoop = firstElementIdx / DataSize;
- const ui64 lastLoop = lastElementIdx / DataSize;
- const ui64 lastOffset = lastElementIdx % DataSize;
- if (firstLoop < lastLoop) {
- for (ui64 i = firstElementIdx % DataSize; i < DataSize; ++i) {
- AtomicSet(Data[i], 0);
- }
- for (ui64 i = 0; i <= lastOffset; ++i) {
- AtomicSet(Data[i], 0);
- }
- } else {
- for (ui64 i = firstElementIdx % DataSize; i <= lastOffset; ++i) {
- AtomicSet(Data[i], 0);
- }
- }
- AtomicSet(LastTimeNs, timeNs);
- }
-};
-
-template <ui64 DataSize>
-struct TMinusOneCpuEstimator {
- static constexpr ui64 BitsSize = DataSize * 64;
- ui64 BeginDelayIdx;
- ui64 EndDelayIdx;
- ui64 Idle;
- ui64 Delay[BitsSize];
-
- ui64 MaxLatencyIncreaseWithOneLessCpu(TCpuLoadLog<DataSize>** logs, i64 logCount, ui64 timeNs, ui64 periodNs) {
- Y_ABORT_UNLESS(logCount > 0);
- ui64 endTimeNs = timeNs;
-
- ui64 lastTimeNs = timeNs;
- for (i64 log_idx = 0; log_idx < logCount; ++log_idx) {
- ui64 x = AtomicGet(logs[log_idx]->LastTimeNs);
- if ((x & 1) == 1) {
- lastTimeNs = Min(lastTimeNs, x);
- } else {
- logs[log_idx]->template RegisterBusyPeriod<false>(endTimeNs, x);
- }
- }
- const ui64 beginTimeNs = periodNs < timeNs ? timeNs - periodNs : 0;
-
- ui64 beginIdx = beginTimeNs / BitDurationNs;
- ui64 lastIdx = lastTimeNs / BitDurationNs;
- ui64 beginElementIdx = beginIdx / 64;
- ui64 lastElementIdx = lastIdx / 64;
-
- BeginDelayIdx = 0;
- EndDelayIdx = 0;
- Idle = 0;
- ui64 maxDelay = 0;
- ui64 bucket = 0;
- for (ui64 idx = beginElementIdx; idx <= lastElementIdx; ++idx) {
- ui64 i = idx % DataSize;
- ui64 input = AtomicGet(logs[0]->Data[i]);
- ui64 all_busy = ~0ull;
- for (i64 log_idx = 1; log_idx < logCount; ++log_idx) {
- ui64 x = AtomicGet(logs[log_idx]->Data[i]);
- all_busy &= x;
- }
- if (!input) {
- if (!bucket) {
- Idle += 64 - PopCount(all_busy);
- continue;
- }
- }
- for (i64 bit_idx = 0; bit_idx < 64; ++bit_idx) {
- ui64 x = (1ull << bit_idx);
- if (all_busy & x) {
- if (input & x) {
- // Push into the queue
- bucket++;
- Delay[EndDelayIdx] = EndDelayIdx;
- ++EndDelayIdx;
- } else {
- // All busy
- }
- } else {
- if (input & x) {
- // Move success
- } else {
- if (bucket) {
- // Remove from the queue
- bucket--;
- ui64 stored = Delay[BeginDelayIdx];
- ++BeginDelayIdx;
- ui64 delay = EndDelayIdx - stored;
- maxDelay = Max(maxDelay, delay);
- //Cerr << "bit_idx: " << bit_idx << " stored: " << stored << " delay: " << delay << Endl;
- } else {
- Idle++;
- }
- }
- }
- }
- }
- if (bucket) {
- ui64 stored = Delay[BeginDelayIdx];
- ui64 delay = EndDelayIdx - stored;
- maxDelay = Max(maxDelay, delay);
- //Cerr << "last stored: " << stored << " delay: " << delay << Endl;
- }
- return maxDelay * BitDurationNs;
- }
-};
-
diff --git a/library/cpp/actors/util/cpu_load_log_ut.cpp b/library/cpp/actors/util/cpu_load_log_ut.cpp
deleted file mode 100644
index 7109123c6e..0000000000
--- a/library/cpp/actors/util/cpu_load_log_ut.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-#include "cpu_load_log.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/random.h>
-#include <util/system/hp_timer.h>
-#include <util/system/sanitizers.h>
-#include <util/system/thread.h>
-
-Y_UNIT_TEST_SUITE(CpuLoadLog) {
-
- TString PrintBits(ui64 x) {
- TStringStream str;
- for (ui64 i = 0; i < 64; ++i) {
- if (x & (1ull << i)) {
- str << "1";
- } else {
- str << "0";
- }
- }
- return str.Str();
- }
-
- Y_UNIT_TEST(FillAll) {
- TCpuLoadLog<5> log(100*BitDurationNs);
- log.RegisterBusyPeriod(101*BitDurationNs);
- log.RegisterBusyPeriod(163*BitDurationNs);
- log.RegisterBusyPeriod(164*BitDurationNs);
- log.RegisterBusyPeriod(165*BitDurationNs);
- log.RegisterBusyPeriod(331*BitDurationNs);
- log.RegisterBusyPeriod(340*BitDurationNs);
- log.RegisterBusyPeriod(420*BitDurationNs);
- log.RegisterBusyPeriod(511*BitDurationNs);
- //for (ui64 i = 0; i < 5; ++i) {
- // Cerr << "i: " << i << " bits: " << PrintBits(log.Data[i]) << Endl;
- //}
- for (ui64 i = 0; i < 5; ++i) {
- UNIT_ASSERT_C((ui64(log.Data[i]) == ~ui64(0)), "Unequal at " << i << "\n got: " << PrintBits(log.Data[i])
- << "\n expected: " << PrintBits(~ui64(0)));
- }
- }
-
- Y_UNIT_TEST(PartialFill) {
- TCpuLoadLog<5> log(0*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(0b0ull));
- log.RegisterBusyPeriod(0*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(0b1ull));
- log.RegisterBusyPeriod(0*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(0b1ull));
- log.RegisterBusyPeriod(1*BitDurationNs/2);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(0b1ull));
- log.RegisterBusyPeriod(1*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(0b11ull));
- log.RegisterIdlePeriod(3*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(0b11ull));
- log.RegisterBusyPeriod(3*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(0b1011ull));
- log.RegisterBusyPeriod(63*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits((~0ull)^0b0100ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[1]), PrintBits(0b0ull));
- log.RegisterBusyPeriod(128*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits((~0ull)^0b0100ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[1]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[2]), PrintBits(0b1ull));
- log.RegisterBusyPeriod(1*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[1]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[2]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[3]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[4]), PrintBits(~0ull));
- log.RegisterBusyPeriod(2*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[1]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[2]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[3]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[4]), PrintBits(~0ull));
- log.RegisterBusyPeriod(64*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[1]), PrintBits(0b1ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[2]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[3]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[4]), PrintBits(~0ull));
- log.RegisterIdlePeriod(128*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[1]), PrintBits(0b1ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[2]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[3]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[4]), PrintBits(~0ull));
- log.RegisterIdlePeriod(192*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[1]), PrintBits(0b1ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[2]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[3]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[4]), PrintBits(~0ull));
- log.RegisterBusyPeriod(192*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(~0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[1]), PrintBits(0b1ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[2]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[3]), PrintBits(0b1ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[4]), PrintBits(~0ull));
- log.RegisterIdlePeriod((192+5*64-1)*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[1]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[2]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[3]), PrintBits(0b1ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[4]), PrintBits(0ull));
- log.RegisterIdlePeriod((192+15*64)*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[0]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[1]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[2]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[3]), PrintBits(0ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log.Data[4]), PrintBits(0ull));
- }
-
- Y_UNIT_TEST(Estimator) {
- TCpuLoadLog<5> *log[10];
- log[0] = new TCpuLoadLog<5>(0*BitDurationNs);
- log[1] = new TCpuLoadLog<5>(0*BitDurationNs);
- TMinusOneCpuEstimator<5> estimator;
-
-
- for (ui64 i = 0; i < 5*64; i+=2) {
- log[0]->RegisterIdlePeriod(i*BitDurationNs);
- log[0]->RegisterBusyPeriod(i*BitDurationNs);
- }
- log[0]->RegisterIdlePeriod((5*64-2)*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log[0]->Data[0]),
- PrintBits(0b0101010101010101010101010101010101010101010101010101010101010101ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log[0]->Data[4]),
- PrintBits(0b0101010101010101010101010101010101010101010101010101010101010101ull));
- for (ui64 i = 0; i < 5*64-1; i+=2) {
- log[1]->RegisterIdlePeriod((i+1)*BitDurationNs);
- log[1]->RegisterBusyPeriod((i+1)*BitDurationNs);
- }
- log[1]->RegisterIdlePeriod((5*64-2+1)*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log[1]->Data[0]),
- PrintBits(0b1010101010101010101010101010101010101010101010101010101010101010ull));
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log[1]->Data[4]),
- PrintBits(0b1010101010101010101010101010101010101010101010101010101010101010ull));
-
- ui64 value = estimator.MaxLatencyIncreaseWithOneLessCpu(log, 2, (5*64)*BitDurationNs-1, 3*64*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(value/BitDurationNs, 1);
-
- value = estimator.MaxLatencyIncreaseWithOneLessCpu(log, 2, (5*64+10)*BitDurationNs, 3*64*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(value/BitDurationNs, 12);
-
- delete log[0];
- delete log[1];
- }
-
- Y_UNIT_TEST(Estimator2) {
- TCpuLoadLog<5> *log[2];
- log[0] = new TCpuLoadLog<5>(0*BitDurationNs);
- log[1] = new TCpuLoadLog<5>(0*BitDurationNs);
- TMinusOneCpuEstimator<5> estimator;
-
- for (ui64 i = 0; i < 5*64; i+=2) {
- log[0]->RegisterIdlePeriod(i*BitDurationNs);
- log[0]->RegisterBusyPeriod(i*BitDurationNs);
- }
- for (ui64 i = 0; i < 5; ++i) {
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log[0]->Data[i]),
- PrintBits(0b0101010101010101010101010101010101010101010101010101010101010101ull));
- }
- for (ui64 i = 0; i < 5*64-1; i+=2) {
- log[1]->RegisterIdlePeriod((i+1)*BitDurationNs);
- log[1]->RegisterBusyPeriod((i+1)*BitDurationNs);
- }
- for (ui64 i = 0; i < 5; ++i) {
- UNIT_ASSERT_VALUES_EQUAL(PrintBits(log[1]->Data[i]),
- PrintBits(0b1010101010101010101010101010101010101010101010101010101010101010ull));
- }
-
- log[0]->Data[2] = ~0ull;
- ui64 value = estimator.MaxLatencyIncreaseWithOneLessCpu(log, 2, (5*64-1)*BitDurationNs, 3*64*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(value/BitDurationNs, 32);
-
- delete log[0];
- delete log[1];
- }
-
- Y_UNIT_TEST(Estimator3) {
- TCpuLoadLog<5> *log[3];
- log[0] = new TCpuLoadLog<5>(0*BitDurationNs);
- log[1] = new TCpuLoadLog<5>(0*BitDurationNs);
- log[2] = new TCpuLoadLog<5>(0*BitDurationNs);
- TMinusOneCpuEstimator<5> estimator;
-
- for (ui64 i = 0; i < 5*64; i+=8) {
- log[0]->RegisterIdlePeriod(i*BitDurationNs);
- log[0]->RegisterBusyPeriod((i+3)*BitDurationNs);
- log[1]->RegisterIdlePeriod(i*BitDurationNs);
- log[1]->RegisterBusyPeriod((i+3)*BitDurationNs);
- log[2]->RegisterIdlePeriod(i*BitDurationNs);
- log[2]->RegisterBusyPeriod((i+3)*BitDurationNs);
- }
- for (ui64 i = 0; i < 5; ++i) {
- for (ui64 n = 0; n < 3; ++n) {
- UNIT_ASSERT_VALUES_EQUAL_C(PrintBits(log[n]->Data[i]),
- PrintBits(0b0000111100001111000011110000111100001111000011110000111100001111ull),
- " i: " << i << " n: " << n);
- }
- }
-
- ui64 value = estimator.MaxLatencyIncreaseWithOneLessCpu(log, 3, (5*64-5)*BitDurationNs, 3*64*BitDurationNs);
- UNIT_ASSERT_VALUES_EQUAL(value/BitDurationNs, 4);
-
- delete log[0];
- delete log[1];
- delete log[2];
- }
- /*
- class TWorkerThread : public ISimpleThread {
- private:
- std::function<void()> Func;
- double Time = 0.0;
-
- public:
- TWorkerThread(std::function<void()> func)
- : Func(std::move(func))
- { }
-
- double GetTime() const {
- return Time;
- }
-
- static THolder<TWorkerThread> Spawn(std::function<void()> func) {
- THolder<TWorkerThread> thread = MakeHolder<TWorkerThread>(std::move(func));
- thread->Start();
- return thread;
- }
-
- private:
- void* ThreadProc() noexcept override {
- THPTimer timer;
- Func();
- Time = timer.Passed();
- return nullptr;
- }
- };
-
- void DoConcurrentPushPop(size_t threads, ui64 perThreadCount) {
- // Concurrency factor 4 is up to 16 threads
-
- auto workerFunc = [&](size_t threadIndex) {
- };
-
- TVector<THolder<TWorkerThread>> workers(threads);
- for (size_t i = 0; i < threads; ++i) {
- workers[i] = TWorkerThread::Spawn([workerFunc, i]() {
- workerFunc(i);
- });
- }
-
- double maxTime = 0;
- for (size_t i = 0; i < threads; ++i) {
- workers[i]->Join();
- maxTime = Max(maxTime, workers[i]->GetTime());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(popped, 0u);
-
- Cerr << "Concurrent with " << threads << " threads: " << maxTime << " seconds" << Endl;
- }
-
- void DoConcurrentPushPop_3times(size_t threads, ui64 perThreadCount) {
- for (size_t i = 0; i < 3; ++i) {
- DoConcurrentPushPop(threads, perThreadCount);
- }
- }
-
- static constexpr ui64 PER_THREAD_COUNT = NSan::PlainOrUnderSanitizer(1000000, 100000);
-
- Y_UNIT_TEST(ConcurrentPushPop_1thread) { DoConcurrentPushPop_3times(1, PER_THREAD_COUNT); }
- */
-}
diff --git a/library/cpp/actors/util/cpumask.h b/library/cpp/actors/util/cpumask.h
deleted file mode 100644
index 29741aa1d6..0000000000
--- a/library/cpp/actors/util/cpumask.h
+++ /dev/null
@@ -1,133 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-#include <library/cpp/containers/stack_vector/stack_vec.h>
-
-#include <util/string/split.h>
-#include <util/generic/yexception.h>
-
-using TCpuId = ui32;
-
-// Simple data structure to operate with set of cpus
-struct TCpuMask {
- TStackVec<bool, 1024> Cpus;
-
- // Creates empty mask
- TCpuMask() {}
-
- // Creates mask with single cpu set
- explicit TCpuMask(TCpuId cpuId) {
- Set(cpuId);
- }
-
- // Initialize mask from raw boolean array
- template <class T>
- TCpuMask(const T* cpus, TCpuId size) {
- Cpus.reserve(size);
- for (TCpuId i = 0; i != size; ++i) {
- Cpus.emplace_back(bool(cpus[i]));
- }
- }
-
- // Parse a numerical list of processors. The numbers are separated by commas and may include ranges. For example: 0,5,7,9-11
- explicit TCpuMask(const TString& cpuList) {
- try {
- for (TStringBuf s : StringSplitter(cpuList).Split(',')) {
- TCpuId l, r;
- if (s.find('-') != TString::npos) {
- StringSplitter(s).Split('-').CollectInto(&l, &r);
- } else {
- l = r = FromString<TCpuId>(s);
- }
- if (r >= Cpus.size()) {
- Cpus.resize(r + 1, false);
- }
- for (TCpuId cpu = l; cpu <= r; cpu++) {
- Cpus[cpu] = true;
- }
- }
- } catch (...) {
- ythrow TWithBackTrace<yexception>() << "Exception occured while parsing cpu list '" << cpuList << "': " << CurrentExceptionMessage();
- }
- }
-
- // Returns size of underlying vector
- TCpuId Size() const {
- return Cpus.size();
- }
-
- // Returns number of set bits in mask
- TCpuId CpuCount() const {
- TCpuId result = 0;
- for (bool value : Cpus) {
- result += value;
- }
- return result;
- }
-
- bool IsEmpty() const {
- for (bool value : Cpus) {
- if (value) {
- return false;
- }
- }
- return true;
- }
-
- bool IsSet(TCpuId cpu) const {
- return cpu < Cpus.size() && Cpus[cpu];
- }
-
- void Set(TCpuId cpu) {
- if (cpu >= Cpus.size()) {
- Cpus.resize(cpu + 1, false);
- }
- Cpus[cpu] = true;
- }
-
- void Reset(TCpuId cpu) {
- if (cpu < Cpus.size()) {
- Cpus[cpu] = false;
- }
- }
-
- void RemoveTrailingZeros() {
- while (!Cpus.empty() && !Cpus.back()) {
- Cpus.pop_back();
- }
- }
-
- explicit operator bool() const {
- return !IsEmpty();
- }
-
- TCpuMask operator &(const TCpuMask& rhs) const {
- TCpuMask result;
- TCpuId size = Max(Size(), rhs.Size());
- result.Cpus.reserve(size);
- for (TCpuId cpu = 0; cpu < size; cpu++) {
- result.Cpus.emplace_back(IsSet(cpu) && rhs.IsSet(cpu));
- }
- return result;
- }
-
- TCpuMask operator |(const TCpuMask& rhs) const {
- TCpuMask result;
- TCpuId size = Max(Size(), rhs.Size());
- result.Cpus.reserve(size);
- for (TCpuId cpu = 0; cpu < size; cpu++) {
- result.Cpus.emplace_back(IsSet(cpu) || rhs.IsSet(cpu));
- }
- return result;
- }
-
- TCpuMask operator -(const TCpuMask& rhs) const {
- TCpuMask result;
- result.Cpus.reserve(Size());
- for (TCpuId cpu = 0; cpu < Size(); cpu++) {
- result.Cpus.emplace_back(IsSet(cpu) && !rhs.IsSet(cpu));
- }
- return result;
- }
-};
diff --git a/library/cpp/actors/util/datetime.h b/library/cpp/actors/util/datetime.h
deleted file mode 100644
index cbec5965d6..0000000000
--- a/library/cpp/actors/util/datetime.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#pragma once
-
-#include <util/system/defaults.h>
-#include <util/system/hp_timer.h>
-#include <util/system/platform.h>
-
-#if defined(_win_)
-#include <intrin.h>
-#pragma intrinsic(__rdtsc)
-#endif // _win_
-
-#if defined(_darwin_) && !defined(_x86_)
-#include <mach/mach_time.h>
-#endif
-
-// GetCycleCount() from util/system/datetime.h uses rdtscp, which is more accurate than rdtsc,
-// but rdtscp disables processor's out-of-order execution, so it can be slow
-Y_FORCE_INLINE ui64 GetCycleCountFast() {
-#if defined(_MSC_VER)
- // Generates the rdtsc instruction, which returns the processor time stamp.
- // The processor time stamp records the number of clock cycles since the last reset.
- return __rdtsc();
-#elif defined(__clang__) && !defined(_arm64_)
- return __builtin_readcyclecounter();
-#elif defined(_x86_64_)
- unsigned hi, lo;
- __asm__ __volatile__("rdtsc"
- : "=a"(lo), "=d"(hi));
- return ((unsigned long long)lo) | (((unsigned long long)hi) << 32);
-#elif defined(_i386_)
- ui64 x;
- __asm__ volatile("rdtsc\n\t"
- : "=A"(x));
- return x;
-#elif defined(_darwin_)
- return mach_absolute_time();
-#elif defined(_arm32_)
- return MicroSeconds();
-#elif defined(_arm64_)
- ui64 x;
-
- __asm__ __volatile__("isb; mrs %0, cntvct_el0"
- : "=r"(x));
-
- return x;
-#else
-#error "unsupported arch"
-#endif
-}
-
-// NHPTimer::GetTime fast analog
-Y_FORCE_INLINE void GetTimeFast(NHPTimer::STime* pTime) noexcept {
- *pTime = GetCycleCountFast();
-}
-
-namespace NActors {
- inline double Ts2Ns(ui64 ts) {
- return NHPTimer::GetSeconds(ts) * 1e9;
- }
-
- inline double Ts2Us(ui64 ts) {
- return NHPTimer::GetSeconds(ts) * 1e6;
- }
-
- inline double Ts2Ms(ui64 ts) {
- return NHPTimer::GetSeconds(ts) * 1e3;
- }
-
- inline ui64 Us2Ts(double us) {
- return ui64(NHPTimer::GetClockRate() * us / 1e6);
- }
-
- struct TTimeTracker {
- ui64 Ts;
- TTimeTracker(): Ts(GetCycleCountFast()) {}
- ui64 Elapsed() {
- ui64 ts = GetCycleCountFast();
- std::swap(Ts, ts);
- return Ts - ts;
- }
- };
-}
diff --git a/library/cpp/actors/util/defs.h b/library/cpp/actors/util/defs.h
deleted file mode 100644
index 70f969753e..0000000000
--- a/library/cpp/actors/util/defs.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-// unique tag to fix pragma once gcc glueing: ./library/actors/util/defs.h
-
-#include <util/system/defaults.h>
-#include <util/generic/bt_exception.h>
-#include <util/generic/noncopyable.h>
-#include <util/generic/ptr.h>
-#include <util/generic/string.h>
-#include <util/generic/yexception.h>
-#include <library/cpp/deprecated/atomic/atomic.h>
-#include <util/system/align.h>
-#include <util/generic/vector.h>
-#include <util/datetime/base.h>
-#include <util/generic/ylimits.h>
-#include "intrinsics.h"
diff --git a/library/cpp/actors/util/funnel_queue.h b/library/cpp/actors/util/funnel_queue.h
deleted file mode 100644
index 15af57b121..0000000000
--- a/library/cpp/actors/util/funnel_queue.h
+++ /dev/null
@@ -1,240 +0,0 @@
-#pragma once
-
-#include <library/cpp/deprecated/atomic/atomic.h>
-#include <util/generic/noncopyable.h>
-
-template <typename ElementType>
-class TFunnelQueue: private TNonCopyable {
-public:
- TFunnelQueue() noexcept
- : Front(nullptr)
- , Back(nullptr)
- {
- }
-
- virtual ~TFunnelQueue() noexcept {
- for (auto entry = Front; entry; entry = DeleteEntry(entry))
- continue;
- }
-
- /// Push element. Can be used from many threads. Return true if is first element.
- bool
- Push(ElementType&& element) noexcept {
- TEntry* const next = NewEntry(static_cast<ElementType&&>(element));
- TEntry* const prev = AtomicSwap(&Back, next);
- AtomicSet(prev ? prev->Next : Front, next);
- return !prev;
- }
-
- /// Extract top element. Must be used only from one thread. Return true if have more.
- bool
- Pop() noexcept {
- if (TEntry* const top = AtomicGet(Front)) {
- const auto last = AtomicCas(&Back, nullptr, top);
- if (last) // This is last element in queue. Queue is empty now.
- AtomicCas(&Front, nullptr, top);
- else // This element is not last.
- for (;;) {
- if (const auto next = AtomicGet(top->Next)) {
- AtomicSet(Front, next);
- break;
- }
- // But Next is null. Wait next assignment in spin lock.
- }
-
- DeleteEntry(top);
- return !last;
- }
-
- return false;
- }
-
- /// Peek top element. Must be used only from one thread.
- ElementType&
- Top() const noexcept {
- return AtomicGet(Front)->Data;
- }
-
- bool
- IsEmpty() const noexcept {
- return !AtomicGet(Front);
- }
-
-protected:
- class TEntry: private TNonCopyable {
- friend class TFunnelQueue;
-
- private:
- explicit TEntry(ElementType&& element) noexcept
- : Data(static_cast<ElementType&&>(element))
- , Next(nullptr)
- {
- }
-
- ~TEntry() noexcept {
- }
-
- public:
- ElementType Data;
- TEntry* volatile Next;
- };
-
- TEntry* volatile Front;
- TEntry* volatile Back;
-
- virtual TEntry* NewEntry(ElementType&& element) noexcept {
- return new TEntry(static_cast<ElementType&&>(element));
- }
-
- virtual TEntry* DeleteEntry(TEntry* entry) noexcept {
- const auto next = entry->Next;
- delete entry;
- return next;
- }
-
-protected:
- struct TEntryIter {
- TEntry* ptr;
-
- ElementType& operator*() {
- return ptr->Data;
- }
-
- ElementType* operator->() {
- return &ptr->Data;
- }
-
- TEntryIter& operator++() {
- ptr = AtomicGet(ptr->Next);
- return *this;
- }
-
- bool operator!=(const TEntryIter& other) const {
- return ptr != other.ptr;
- }
-
- bool operator==(const TEntryIter& other) const {
- return ptr == other.ptr;
- }
- };
-
- struct TConstEntryIter {
- const TEntry* ptr;
-
- const ElementType& operator*() {
- return ptr->Data;
- }
-
- const ElementType* operator->() {
- return &ptr->Data;
- }
-
- TEntryIter& operator++() {
- ptr = AtomicGet(ptr->Next);
- return *this;
- }
-
- bool operator!=(const TConstEntryIter& other) const {
- return ptr != other.ptr;
- }
-
- bool operator==(const TConstEntryIter& other) const {
- return ptr == other.ptr;
- }
- };
-
-public:
- using const_iterator = TConstEntryIter;
- using iterator = TEntryIter;
-
- iterator begin() {
- return {AtomicGet(Front)};
- }
- const_iterator cbegin() {
- return {AtomicGet(Front)};
- }
- const_iterator begin() const {
- return {AtomicGet(Front)};
- }
-
- iterator end() {
- return {nullptr};
- }
- const_iterator cend() {
- return {nullptr};
- }
- const_iterator end() const {
- return {nullptr};
- }
-};
-
-template <typename ElementType>
-class TPooledFunnelQueue: public TFunnelQueue<ElementType> {
-public:
- TPooledFunnelQueue() noexcept
- : Stack(nullptr)
- {
- }
-
- virtual ~TPooledFunnelQueue() noexcept override {
- for (auto entry = TBase::Front; entry; entry = TBase::DeleteEntry(entry))
- continue;
- for (auto entry = Stack; entry; entry = TBase::DeleteEntry(entry))
- continue;
- TBase::Back = TBase::Front = Stack = nullptr;
- }
-
-private:
- typedef TFunnelQueue<ElementType> TBase;
-
- typename TBase::TEntry* volatile Stack;
-
-protected:
- virtual typename TBase::TEntry* NewEntry(ElementType&& element) noexcept override {
- while (const auto top = AtomicGet(Stack))
- if (AtomicCas(&Stack, top->Next, top)) {
- top->Data = static_cast<ElementType&&>(element);
- AtomicSet(top->Next, nullptr);
- return top;
- }
-
- return TBase::NewEntry(static_cast<ElementType&&>(element));
- }
-
- virtual typename TBase::TEntry* DeleteEntry(typename TBase::TEntry* entry) noexcept override {
- entry->Data = ElementType();
- const auto next = entry->Next;
- do
- AtomicSet(entry->Next, AtomicGet(Stack));
- while (!AtomicCas(&Stack, entry, entry->Next));
- return next;
- }
-};
-
-template <typename ElementType, template <typename T> class TQueueType = TFunnelQueue>
-class TCountedFunnelQueue: public TQueueType<ElementType> {
-public:
- TCountedFunnelQueue() noexcept
- : Count(0)
- {
- }
-
- TAtomicBase GetSize() const noexcept {
- return AtomicGet(Count);
- }
-
-private:
- typedef TQueueType<ElementType> TBase;
-
- virtual typename TBase::TEntry* NewEntry(ElementType&& element) noexcept override {
- AtomicAdd(Count, 1);
- return TBase::NewEntry(static_cast<ElementType&&>(element));
- }
-
- virtual typename TBase::TEntry* DeleteEntry(typename TBase::TEntry* entry) noexcept override {
- AtomicSub(Count, 1);
- return TBase::DeleteEntry(entry);
- }
-
- TAtomic Count;
-};
diff --git a/library/cpp/actors/util/futex.h b/library/cpp/actors/util/futex.h
deleted file mode 100644
index c193f8d128..0000000000
--- a/library/cpp/actors/util/futex.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#ifdef _linux_
-
-#include <linux/futex.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-
-static long SysFutex(void* addr1, int op, int val1, struct timespec* timeout, void* addr2, int val3) {
- return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
-}
-
-#endif
diff --git a/library/cpp/actors/util/intrinsics.h b/library/cpp/actors/util/intrinsics.h
deleted file mode 100644
index c02b633b70..0000000000
--- a/library/cpp/actors/util/intrinsics.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#pragma once
-
-#include <util/system/defaults.h>
-#include <library/cpp/deprecated/atomic/atomic.h>
-#include <util/system/spinlock.h>
-
-#include <library/cpp/sse/sse.h> // The header chooses appropriate SSE support
-
-static_assert(sizeof(TAtomic) == 8, "expect sizeof(TAtomic) == 8");
-
-// we need explicit 32 bit operations to keep cache-line friendly packs
-// so have to define some atomics additionaly to arcadia one
-#ifdef _win_
-#pragma intrinsic(_InterlockedCompareExchange)
-#pragma intrinsic(_InterlockedExchangeAdd)
-#pragma intrinsic(_InterlockedIncrement)
-#pragma intrinsic(_InterlockedDecrement)
-#endif
-
-inline bool AtomicUi32Cas(volatile ui32* a, ui32 exchange, ui32 compare) {
-#ifdef _win_
- return _InterlockedCompareExchange((volatile long*)a, exchange, compare) == (long)compare;
-#else
- ui32 expected = compare;
- return __atomic_compare_exchange_n(a, &expected, exchange, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
-#endif
-}
-
-inline ui32 AtomicUi32Add(volatile ui32* a, ui32 add) {
-#ifdef _win_
- return _InterlockedExchangeAdd((volatile long*)a, add) + add;
-#else
- return __atomic_add_fetch(a, add, __ATOMIC_SEQ_CST);
-#endif
-}
-
-inline ui32 AtomicUi32Sub(volatile ui32* a, ui32 sub) {
-#ifdef _win_
- return _InterlockedExchangeAdd((volatile long*)a, -(long)sub) - sub;
-#else
- return __atomic_sub_fetch(a, sub, __ATOMIC_SEQ_CST);
-#endif
-}
-
-inline ui32 AtomicUi32Increment(volatile ui32* a) {
-#ifdef _win_
- return _InterlockedIncrement((volatile long*)a);
-#else
- return __atomic_add_fetch(a, 1, __ATOMIC_SEQ_CST);
-#endif
-}
-
-inline ui32 AtomicUi32Decrement(volatile ui32* a) {
-#ifdef _win_
- return _InterlockedDecrement((volatile long*)a);
-#else
- return __atomic_sub_fetch(a, 1, __ATOMIC_SEQ_CST);
-#endif
-}
-
-template <typename T>
-inline void AtomicStore(volatile T* a, T x) {
- static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value");
-#ifdef _win_
- *a = x;
-#else
- __atomic_store_n(a, x, __ATOMIC_RELEASE);
-#endif
-}
-
-template <typename T>
-inline void RelaxedStore(volatile T* a, T x) {
- static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value");
-#ifdef _win_
- *a = x;
-#else
- __atomic_store_n(a, x, __ATOMIC_RELAXED);
-#endif
-}
-
-template <typename T>
-inline T AtomicLoad(volatile T* a) {
-#ifdef _win_
- return *a;
-#else
- return __atomic_load_n(a, __ATOMIC_ACQUIRE);
-#endif
-}
-
-template <typename T>
-inline T RelaxedLoad(volatile T* a) {
-#ifdef _win_
- return *a;
-#else
- return __atomic_load_n(a, __ATOMIC_RELAXED);
-#endif
-}
diff --git a/library/cpp/actors/util/local_process_key.h b/library/cpp/actors/util/local_process_key.h
deleted file mode 100644
index bff8bef81b..0000000000
--- a/library/cpp/actors/util/local_process_key.h
+++ /dev/null
@@ -1,157 +0,0 @@
-#pragma once
-
-#include <util/string/builder.h>
-#include <util/system/mutex.h>
-#include <util/generic/strbuf.h>
-#include <util/generic/vector.h>
-#include <util/generic/hash.h>
-#include <util/generic/singleton.h>
-#include <util/generic/serialized_enum.h>
-
-class TLocalProcessKeyStateIndexLimiter {
-public:
- static constexpr ui32 GetMaxKeysCount() {
- return 10000;
- }
-};
-
-template <class T>
-class TLocalProcessKeyStateIndexConstructor {
-public:
-};
-
-template <typename T>
-class TLocalProcessKeyState {
-
-template <typename U, const char* Name>
-friend class TLocalProcessKey;
-template <typename U, class TClass, ui32 KeyLengthLimit>
-friend class TLocalProcessExtKey;
-template <typename U, typename EnumT>
-friend class TEnumProcessKey;
-
-public:
- static TLocalProcessKeyState& GetInstance() {
- return *Singleton<TLocalProcessKeyState<T>>();
- }
-
- ui32 GetCount() const {
- return MaxKeysCount;
- }
-
- TStringBuf GetNameByIndex(size_t index) const {
- Y_ABORT_UNLESS(index < Names.size());
- return Names[index];
- }
-
- size_t GetIndexByName(TStringBuf name) const {
- TGuard<TMutex> g(Mutex);
- auto it = Map.find(name);
- Y_ENSURE(it != Map.end());
- return it->second;
- }
-
- TLocalProcessKeyState() {
- Names.resize(MaxKeysCount);
- }
-
- size_t Register(TStringBuf name) {
- TGuard<TMutex> g(Mutex);
- auto it = Map.find(name);
- if (it != Map.end()) {
- return it->second;
- }
- const ui32 index = TLocalProcessKeyStateIndexConstructor<T>::BuildCurrentIndex(name, Names.size());
- auto x = Map.emplace(name, index);
- if (x.second) {
- Y_ABORT_UNLESS(index < Names.size(), "a lot of actors or tags for memory monitoring");
- Names[index] = name;
- }
-
- return x.first->second;
- }
-
-private:
-
- static constexpr ui32 MaxKeysCount = TLocalProcessKeyStateIndexLimiter::GetMaxKeysCount();
-
-private:
- TVector<TString> Names;
- THashMap<TString, size_t> Map;
- TMutex Mutex;
-};
-
-template <typename T, const char* Name>
-class TLocalProcessKey {
-public:
- static TStringBuf GetName() {
- return Name;
- }
-
- static size_t GetIndex() {
- return Index;
- }
-
-private:
- inline static size_t Index = TLocalProcessKeyState<T>::GetInstance().Register(Name);
-};
-
-template <typename T, class TClass, ui32 KeyLengthLimit = 0>
-class TLocalProcessExtKey {
-public:
- static TStringBuf GetName() {
- return Name;
- }
-
- static size_t GetIndex() {
- return Index;
- }
-
-private:
-
- static TString TypeNameRobust() {
- const TString className = TypeName<TClass>();
- if (KeyLengthLimit && className.size() > KeyLengthLimit) {
- return className.substr(0, KeyLengthLimit - 3) + "...";
- } else {
- return className;
- }
- }
-
- static const inline TString Name = TypeName<TClass>();
- inline static size_t Index = TLocalProcessKeyState<T>::GetInstance().Register(TypeNameRobust());
-};
-
-template <typename T, typename EnumT>
-class TEnumProcessKey {
-public:
- static TStringBuf GetName(const EnumT key) {
- return TLocalProcessKeyState<T>::GetInstance().GetNameByIndex(GetIndex(key));
- }
-
- static size_t GetIndex(const EnumT key) {
- ui32 index = static_cast<ui32>(key);
- Y_ABORT_UNLESS(index < Enum2Index.size());
- return Enum2Index[index];
- }
-
-private:
- inline static TVector<size_t> RegisterAll() {
- static_assert(std::is_enum<EnumT>::value, "Enum is required");
-
- TVector<size_t> enum2Index;
- auto names = GetEnumNames<EnumT>();
- ui32 maxId = 0;
- for (const auto& [k, v] : names) {
- maxId = Max(maxId, static_cast<ui32>(k));
- }
- enum2Index.resize(maxId + 1);
- for (const auto& [k, v] : names) {
- ui32 enumId = static_cast<ui32>(k);
- enum2Index[enumId] = TLocalProcessKeyState<T>::GetInstance().Register(v);
- }
- return enum2Index;
- }
-
- inline static TVector<size_t> Enum2Index = RegisterAll();
-};
diff --git a/library/cpp/actors/util/memory_track.cpp b/library/cpp/actors/util/memory_track.cpp
deleted file mode 100644
index 5f422116be..0000000000
--- a/library/cpp/actors/util/memory_track.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "memory_track.h"
-#include "memory_tracker.h"
-
-namespace NActors {
-namespace NMemory {
-
-namespace NPrivate {
-
-TThreadLocalInfo::TThreadLocalInfo()
- : Metrics(TMemoryTracker::Instance()->GetCount())
-{
- TMemoryTracker::Instance()->OnCreateThread(this);
-}
-
-TThreadLocalInfo::~TThreadLocalInfo() {
- TMemoryTracker::Instance()->OnDestroyThread(this);
-}
-
-TMetric* TThreadLocalInfo::GetMetric(size_t index) {
- if (Y_UNLIKELY(index >= Metrics.size())) {
- return &Null;
- }
- return &Metrics[index];
-}
-
-const std::vector<TMetric>& TThreadLocalInfo::GetMetrics() const {
- return Metrics;
-}
-
-size_t TBaseLabel::RegisterStaticMemoryLabel(const char* name, bool hasSensor) {
- return TMemoryTracker::Instance()->RegisterStaticMemoryLabel(name, hasSensor);
-}
-
-}
-
-}
-}
-
diff --git a/library/cpp/actors/util/memory_track.h b/library/cpp/actors/util/memory_track.h
deleted file mode 100644
index 6035333eeb..0000000000
--- a/library/cpp/actors/util/memory_track.h
+++ /dev/null
@@ -1,293 +0,0 @@
-#pragma once
-
-#include <vector>
-
-#include <util/system/type_name.h>
-#include <util/thread/singleton.h>
-
-#define ENABLE_MEMORY_TRACKING
-
-namespace NActors {
-namespace NMemory {
-
-namespace NPrivate {
-
-class TMetric {
- std::atomic<ssize_t> Memory;
- std::atomic<ssize_t> Count;
-
- void Copy(const TMetric& other) {
- Memory.store(other.GetMemory(), std::memory_order_relaxed);
- Count.store(other.GetCount(), std::memory_order_relaxed);
- }
-
-public:
- TMetric()
- : Memory(0)
- , Count(0)
- {}
-
- inline TMetric(const TMetric& other) {
- Copy(other);
- }
-
- inline TMetric(TMetric&& other) {
- Copy(other);
- }
-
- inline TMetric& operator=(const TMetric& other) {
- Copy(other);
- return *this;
- }
-
- inline TMetric& operator=(TMetric&& other) {
- Copy(other);
- return *this;
- }
-
- inline ssize_t GetMemory() const {
- return Memory.load(std::memory_order_relaxed);
- }
- inline void SetMemory(ssize_t value) {
- Memory.store(value, std::memory_order_relaxed);
- }
-
- inline ssize_t GetCount() const {
- return Count.load(std::memory_order_relaxed);
- }
- inline void SetCount(ssize_t value) {
- Count.store(value, std::memory_order_relaxed);
- }
-
- inline void operator+=(const TMetric& other) {
- SetMemory(GetMemory() + other.GetMemory());
- SetCount(GetCount() + other.GetCount());
- }
-
- inline void CalculatePeak(const TMetric& other) {
- SetMemory(Max(GetMemory(), other.GetMemory()));
- SetCount(Max(GetCount(), other.GetCount()));
- }
-
- inline void Add(size_t size) {
- SetMemory(GetMemory() + size);
- SetCount(GetCount() + 1);
- }
-
- inline void Sub(size_t size) {
- SetMemory(GetMemory() - size);
- SetCount(GetCount() - 1);
- }
-};
-
-
-class TThreadLocalInfo {
-public:
- TThreadLocalInfo();
- ~TThreadLocalInfo();
-
- TMetric* GetMetric(size_t index);
- const std::vector<TMetric>& GetMetrics() const;
-
-private:
- std::vector<TMetric> Metrics;
-
- inline static TMetric Null = {};
-};
-
-
-class TBaseLabel {
-protected:
- static size_t RegisterStaticMemoryLabel(const char* name, bool hasSensor);
-
- inline static TMetric* GetLocalMetric(size_t index) {
- return FastTlsSingleton<TThreadLocalInfo>()->GetMetric(index);
- }
-};
-
-
-template <const char* Name>
-class TNameLabel
- : TBaseLabel
-{
-public:
- static void Add(size_t size) {
-#if defined(ENABLE_MEMORY_TRACKING)
- Y_UNUSED(MetricInit);
-
- if (Y_UNLIKELY(!Metric)) {
- Metric = GetLocalMetric(Index);
- }
-
- Metric->Add(size);
-#else
- Y_UNUSED(size);
-#endif
- }
-
- static void Sub(size_t size) {
-#if defined(ENABLE_MEMORY_TRACKING)
- Y_UNUSED(MetricInit);
-
- if (Y_UNLIKELY(!Metric)) {
- Metric = GetLocalMetric(Index);
- }
-
- Metric->Sub(size);
-#else
- Y_UNUSED(size);
-#endif
- }
-
-private:
-#if defined(ENABLE_MEMORY_TRACKING)
- inline static size_t Index = Max<size_t>();
- inline static struct TMetricInit {
- TMetricInit() {
- Index = RegisterStaticMemoryLabel(Name, true);
- }
- } MetricInit;
-
- inline static thread_local TMetric* Metric = nullptr;
-#endif
-};
-
-
-template <typename TType>
-class TTypeLabel
- : TBaseLabel
-{
-public:
- static void Add(size_t size) {
-#if defined(ENABLE_MEMORY_TRACKING)
- Y_UNUSED(MetricInit);
-
- if (Y_UNLIKELY(!Metric)) {
- Metric = GetLocalMetric(Index);
- }
-
- Metric->Add(size);
-#else
- Y_UNUSED(size);
-#endif
- }
-
- static void Sub(size_t size) {
-#if defined(ENABLE_MEMORY_TRACKING)
- Y_UNUSED(MetricInit);
-
- if (Y_UNLIKELY(!Metric)) {
- Metric = GetLocalMetric(Index);
- }
-
- Metric->Sub(size);
-#else
- Y_UNUSED(size);
-#endif
- }
-
-private:
-#if defined(ENABLE_MEMORY_TRACKING)
- inline static size_t Index = Max<size_t>();
- inline static struct TMetricInit {
- TMetricInit() {
- Index = RegisterStaticMemoryLabel(TypeName<TType>().c_str(), false);
- }
- } MetricInit;
-
- inline static thread_local TMetric* Metric = nullptr;
-#endif
-};
-
-
-template <typename T>
-struct TTrackHelper {
-#if defined(ENABLE_MEMORY_TRACKING)
- void* operator new(size_t size) {
- T::Add(size);
- return malloc(size);
- }
-
- void* operator new[](size_t size) {
- T::Add(size);
- return malloc(size);
- }
-
- void operator delete(void* ptr, size_t size) {
- T::Sub(size);
- free(ptr);
- }
-
- void operator delete[](void* ptr, size_t size) {
- T::Sub(size);
- free(ptr);
- }
-#endif
-};
-
-template <typename TType, typename T>
-struct TAllocHelper {
- typedef size_t size_type;
- typedef TType value_type;
- typedef TType* pointer;
- typedef const TType* const_pointer;
-
- struct propagate_on_container_copy_assignment : public std::false_type {};
- struct propagate_on_container_move_assignment : public std::false_type {};
- struct propagate_on_container_swap : public std::false_type {};
-
- pointer allocate(size_type n, const void* hint = nullptr) {
- Y_UNUSED(hint);
- auto size = n * sizeof(TType);
- T::Add(size);
- return (pointer)malloc(size);
- }
-
- void deallocate(pointer ptr, size_t n) {
- auto size = n * sizeof(TType);
- T::Sub(size);
- free((void*)ptr);
- }
-};
-
-} // NPrivate
-
-
-template <const char* Name>
-using TLabel = NPrivate::TNameLabel<Name>;
-
-template <typename TType, const char* Name = nullptr>
-struct TTrack
- : public NPrivate::TTrackHelper<NPrivate::TNameLabel<Name>>
-{
-};
-
-template <typename TType>
-struct TTrack<TType, nullptr>
- : public NPrivate::TTrackHelper<NPrivate::TTypeLabel<TType>>
-{
-};
-
-template <typename TType, const char* Name = nullptr>
-struct TAlloc
- : public NPrivate::TAllocHelper<TType, NPrivate::TNameLabel<Name>>
-{
- template<typename U>
- struct rebind {
- typedef TAlloc<U, Name> other;
- };
-};
-
-template <typename TType>
-struct TAlloc<TType, nullptr>
- : public NPrivate::TAllocHelper<TType, NPrivate::TTypeLabel<TType>>
-{
- template<typename U>
- struct rebind {
- typedef TAlloc<U> other;
- };
-};
-
-}
-}
-
diff --git a/library/cpp/actors/util/memory_tracker.cpp b/library/cpp/actors/util/memory_tracker.cpp
deleted file mode 100644
index 8a12452c71..0000000000
--- a/library/cpp/actors/util/memory_tracker.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "memory_tracker.h"
-
-#include <util/generic/xrange.h>
-
-namespace NActors {
-namespace NMemory {
-
-namespace NPrivate {
-
-TMemoryTracker* TMemoryTracker::Instance() {
- return SingletonWithPriority<TMemoryTracker, 0>();
-}
-
-void TMemoryTracker::Initialize() {
- GlobalMetrics.resize(Indices.size());
-}
-
-const std::map<TString, size_t>& TMemoryTracker::GetMetricIndices() const {
- return Indices;
-}
-
-const std::unordered_set<size_t>& TMemoryTracker::GetSensors() const {
- return Sensors;
-}
-
-TString TMemoryTracker::GetName(size_t index) const {
- return Names[index];
-}
-
-size_t TMemoryTracker::GetCount() const {
- return Indices.size();
-}
-
-void TMemoryTracker::GatherMetrics(std::vector<TMetric>& metrics) const {
- metrics.resize(0);
- auto count = GetCount();
-
- if (!count || GlobalMetrics.size() != count) {
- return;
- }
-
- TReadGuard guard(LockThreadInfo);
-
- metrics.resize(count);
- for (size_t i : xrange(count)) {
- metrics[i] += GlobalMetrics[i];
- }
-
- for (auto info : ThreadInfo) {
- auto& localMetrics = info->GetMetrics();
- if (localMetrics.size() == count) {
- for (size_t i : xrange(count)) {
- metrics[i] += localMetrics[i];
- }
- }
- }
-}
-
-size_t TMemoryTracker::RegisterStaticMemoryLabel(const char* name, bool hasSensor) {
- size_t index = 0;
- auto found = Indices.find(name);
- if (found == Indices.end()) {
- TString str(name);
- auto next = Names.size();
- Indices.emplace(str, next);
- Names.push_back(str);
- index = next;
- } else {
- index = found->second;
- }
-
- if (hasSensor) {
- Sensors.emplace(index);
- }
- return index;
-}
-
-void TMemoryTracker::OnCreateThread(TThreadLocalInfo* info) {
- TWriteGuard guard(LockThreadInfo);
- ThreadInfo.insert(info);
-}
-
-void TMemoryTracker::OnDestroyThread(TThreadLocalInfo* info) {
- TWriteGuard guard(LockThreadInfo);
-
- auto count = GetCount();
- if (count && GlobalMetrics.size() == count) {
- const auto& localMetrics = info->GetMetrics();
- if (localMetrics.size() == count) {
- for (size_t i : xrange(count)) {
- GlobalMetrics[i] += localMetrics[i];
- }
- }
- }
-
- ThreadInfo.erase(info);
-}
-
-}
-
-}
-}
-
diff --git a/library/cpp/actors/util/memory_tracker.h b/library/cpp/actors/util/memory_tracker.h
deleted file mode 100644
index e74508191b..0000000000
--- a/library/cpp/actors/util/memory_tracker.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#include "memory_track.h"
-
-#include <map>
-#include <unordered_map>
-#include <unordered_set>
-
-#include <util/system/rwlock.h>
-
-namespace NActors {
-namespace NMemory {
-
-namespace NPrivate {
-
-class TMemoryTracker {
-public:
- static TMemoryTracker* Instance();
-
- void Initialize();
-
- const std::map<TString, size_t>& GetMetricIndices() const;
- const std::unordered_set<size_t>& GetSensors() const;
- TString GetName(size_t index) const;
- size_t GetCount() const;
-
- void GatherMetrics(std::vector<TMetric>& metrics) const;
-
-private:
- size_t RegisterStaticMemoryLabel(const char* name, bool hasSensor);
-
- void OnCreateThread(TThreadLocalInfo* info);
- void OnDestroyThread(TThreadLocalInfo* info);
-
-private:
- std::map<TString, size_t> Indices;
- std::vector<TString> Names;
-
- std::vector<TMetric> GlobalMetrics;
-
- std::unordered_set<size_t> Sensors;
-
- std::unordered_set<TThreadLocalInfo*> ThreadInfo;
- TRWMutex LockThreadInfo;
-
- friend class TThreadLocalInfo;
- friend class TBaseLabel;
-};
-
-}
-
-}
-}
diff --git a/library/cpp/actors/util/memory_tracker_ut.cpp b/library/cpp/actors/util/memory_tracker_ut.cpp
deleted file mode 100644
index 1b8eff7cc5..0000000000
--- a/library/cpp/actors/util/memory_tracker_ut.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-#include "memory_tracker.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/system/hp_timer.h>
-#include <util/system/thread.h>
-
-namespace NActors {
-namespace NMemory {
-
-Y_UNIT_TEST_SUITE(TMemoryTrackerTest) {
-
-#if defined(ENABLE_MEMORY_TRACKING)
-
-using namespace NPrivate;
-
-size_t FindLabelIndex(const char* label) {
- auto indices = TMemoryTracker::Instance()->GetMetricIndices();
- auto it = indices.find(label);
- UNIT_ASSERT(it != indices.end());
- return it->second;
-}
-
-
-struct TTypeLabeled
- : public NActors::NMemory::TTrack<TTypeLabeled>
-{
- char payload[16];
-};
-
-static constexpr char NamedLabel[] = "NamedLabel";
-
-struct TNameLabeled
- : public NActors::NMemory::TTrack<TNameLabeled, NamedLabel>
-{
- char payload[32];
-};
-
-#ifndef _win_
-Y_UNIT_TEST(Gathering)
-{
- TMemoryTracker::Instance()->Initialize();
-
- auto* typed = new TTypeLabeled;
- auto* typedArray = new TTypeLabeled[3];
-
- auto* named = new TNameLabeled;
- auto* namedArray = new TNameLabeled[5];
- NActors::NMemory::TLabel<NamedLabel>::Add(100);
-
- std::vector<TMetric> metrics;
- TMemoryTracker::Instance()->GatherMetrics(metrics);
-
- auto typeIndex = FindLabelIndex(TypeName<TTypeLabeled>().c_str());
- UNIT_ASSERT(typeIndex < metrics.size());
- UNIT_ASSERT(metrics[typeIndex].GetMemory() == sizeof(TTypeLabeled) * 4 + sizeof(size_t));
- UNIT_ASSERT(metrics[typeIndex].GetCount() == 2);
-
- auto nameIndex = FindLabelIndex(NamedLabel);
- UNIT_ASSERT(nameIndex < metrics.size());
- UNIT_ASSERT(metrics[nameIndex].GetMemory() == sizeof(TNameLabeled) * 6 + sizeof(size_t) + 100);
- UNIT_ASSERT(metrics[nameIndex].GetCount() == 3);
-
- NActors::NMemory::TLabel<NamedLabel>::Sub(100);
- delete [] namedArray;
- delete named;
-
- delete [] typedArray;
- delete typed;
-
- TMemoryTracker::Instance()->GatherMetrics(metrics);
-
- UNIT_ASSERT(metrics[typeIndex].GetMemory() == 0);
- UNIT_ASSERT(metrics[typeIndex].GetCount() == 0);
-
- UNIT_ASSERT(metrics[nameIndex].GetMemory() == 0);
- UNIT_ASSERT(metrics[nameIndex].GetCount() == 0);
-}
-#endif
-
-static constexpr char InContainerLabel[] = "InContainerLabel";
-
-struct TInContainer {
- char payload[16];
-};
-
-Y_UNIT_TEST(Containers) {
- TMemoryTracker::Instance()->Initialize();
-
- std::vector<TInContainer, NActors::NMemory::TAlloc<TInContainer>> vecT;
- vecT.resize(5);
-
- std::vector<TInContainer, NActors::NMemory::TAlloc<TInContainer, InContainerLabel>> vecN;
- vecN.resize(7);
-
- using TKey = int;
-
- std::map<TKey, TInContainer, std::less<TKey>,
- NActors::NMemory::TAlloc<std::pair<const TKey, TInContainer>>> mapT;
- mapT.emplace(0, TInContainer());
- mapT.emplace(1, TInContainer());
-
- std::map<TKey, TInContainer, std::less<TKey>,
- NActors::NMemory::TAlloc<std::pair<const TKey, TInContainer>, InContainerLabel>> mapN;
- mapN.emplace(0, TInContainer());
-
- std::unordered_map<TKey, TInContainer, std::hash<TKey>, std::equal_to<TKey>,
- NActors::NMemory::TAlloc<std::pair<const TKey, TInContainer>>> umapT;
- umapT.emplace(0, TInContainer());
-
- std::unordered_map<TKey, TInContainer, std::hash<TKey>, std::equal_to<TKey>,
- NActors::NMemory::TAlloc<std::pair<const TKey, TInContainer>, InContainerLabel>> umapN;
- umapN.emplace(0, TInContainer());
- umapN.emplace(1, TInContainer());
-
- std::vector<TMetric> metrics;
- TMemoryTracker::Instance()->GatherMetrics(metrics);
-
- auto indices = TMemoryTracker::Instance()->GetMetricIndices();
- for (auto& [name, index] : indices) {
- Cerr << "---- " << name
- << ": memory = " << metrics[index].GetMemory()
- << ", count = " << metrics[index].GetCount() << Endl;
- }
-
- auto vecTIndex = FindLabelIndex(TypeName<TInContainer>().c_str());
- UNIT_ASSERT(metrics[vecTIndex].GetMemory() >= ssize_t(sizeof(TInContainer) * 5));
- UNIT_ASSERT(metrics[vecTIndex].GetCount() == 1);
-
- auto labelIndex = FindLabelIndex(InContainerLabel);
- UNIT_ASSERT(metrics[labelIndex].GetCount() == 5);
- UNIT_ASSERT(metrics[labelIndex].GetMemory() >= ssize_t(
- sizeof(TInContainer) * 7 +
- sizeof(decltype(mapN)::value_type) +
- sizeof(decltype(umapN)::value_type) * 2));
-}
-
-
-static constexpr char InThreadLabel[] = "InThreadLabel";
-
-struct TInThread
- : public NActors::NMemory::TTrack<TInThread, InThreadLabel>
-{
- char payload[16];
-};
-
-void* ThreadProc(void*) {
- return new TInThread;
-}
-
-Y_UNIT_TEST(Threads) {
- TMemoryTracker::Instance()->Initialize();
-
- auto index = FindLabelIndex(InThreadLabel);
-
- auto* object1 = new TInThread;
-
- std::vector<TMetric> metrics;
- TMemoryTracker::Instance()->GatherMetrics(metrics);
- UNIT_ASSERT(metrics[index].GetMemory() == sizeof(TInThread));
- UNIT_ASSERT(metrics[index].GetCount() == 1);
-
- TThread thread(&ThreadProc, nullptr);
- thread.Start();
- auto* object2 = static_cast<TInThread*>(thread.Join());
-
- TMemoryTracker::Instance()->GatherMetrics(metrics);
- UNIT_ASSERT(metrics[index].GetMemory() == sizeof(TInThread) * 2);
- UNIT_ASSERT(metrics[index].GetCount() == 2);
-
- delete object2;
-
- TMemoryTracker::Instance()->GatherMetrics(metrics);
- UNIT_ASSERT(metrics[index].GetMemory() == sizeof(TInThread));
- UNIT_ASSERT(metrics[index].GetCount() == 1);
-
- delete object1;
-}
-
-
-struct TNotTracked {
- char payload[16];
-};
-
-struct TTracked
- : public NActors::NMemory::TTrack<TTracked>
-{
- char payload[16];
-};
-
-template <typename T>
-double MeasureAllocations() {
- constexpr size_t objectsCount = 4 << 20;
-
- std::vector<T*> objects;
- objects.resize(objectsCount);
-
- THPTimer timer;
-
- for (size_t i = 0; i < objectsCount; ++i) {
- objects[i] = new T;
- }
-
- for (size_t i = 0; i < objectsCount; ++i) {
- delete objects[i];
- }
-
- auto seconds = timer.Passed();
- Cerr << "---- objects: " << objectsCount << ", time: " << seconds << Endl;
- return seconds;
-}
-
-Y_UNIT_TEST(Performance) {
- TMemoryTracker::Instance()->Initialize();
-
- constexpr size_t Runs = 16;
-
- Cerr << "---- warmup" << Endl;
- MeasureAllocations<TNotTracked>();
- MeasureAllocations<TTracked>();
-
- std::vector<double> noTrack;
- std::vector<double> track;
-
- for (size_t run = 0; run < Runs; ++run) {
- Cerr << "---- no track" << Endl;
- auto time = MeasureAllocations<TNotTracked>();
- noTrack.push_back(time);
-
- Cerr << "---- track" << Endl;
- time = MeasureAllocations<TTracked>();
- track.push_back(time);
- }
-
- double meanNoTrack = 0, stddevNoTrack = 0;
- double meanTrack = 0, stddevTrack = 0;
- for (size_t i = 0; i < Runs; ++i) {
- meanNoTrack += noTrack[i];
- meanTrack += track[i];
- }
- meanNoTrack /= Runs;
- meanTrack /= Runs;
-
- auto sqr = [](double val) { return val * val; };
-
- for (size_t i = 0; i < Runs; ++i) {
- stddevNoTrack += sqr(noTrack[i] - meanNoTrack);
- stddevTrack += sqr(track[i] - meanTrack);
- }
- stddevNoTrack = sqrt(stddevNoTrack / (Runs - 1));
- stddevTrack = sqrt(stddevTrack / (Runs - 1));
-
- Cerr << "---- no track - mean: " << meanNoTrack << ", stddev: " << stddevNoTrack << Endl;
- Cerr << "---- track - mean: " << meanTrack << ", stddev: " << stddevTrack << Endl;
- Cerr << "---- tracking is slower by " << int((meanTrack / meanNoTrack - 1.0) * 100) << "%" << Endl;
-}
-
-#endif
-
-}
-
-}
-}
diff --git a/library/cpp/actors/util/named_tuple.h b/library/cpp/actors/util/named_tuple.h
deleted file mode 100644
index 67f185bba8..0000000000
--- a/library/cpp/actors/util/named_tuple.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-template <typename TDerived>
-struct TNamedTupleBase {
- friend bool operator==(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() == y.ConvertToTuple();
- }
-
- friend bool operator!=(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() != y.ConvertToTuple();
- }
-
- friend bool operator<(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() < y.ConvertToTuple();
- }
-
- friend bool operator<=(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() <= y.ConvertToTuple();
- }
-
- friend bool operator>(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() > y.ConvertToTuple();
- }
-
- friend bool operator>=(const TDerived& x, const TDerived& y) {
- return x.ConvertToTuple() >= y.ConvertToTuple();
- }
-};
diff --git a/library/cpp/actors/util/queue_chunk.h b/library/cpp/actors/util/queue_chunk.h
deleted file mode 100644
index 8a4e02d8cb..0000000000
--- a/library/cpp/actors/util/queue_chunk.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-template <typename T, ui32 TSize, typename TDerived>
-struct TQueueChunkDerived {
- static const ui32 EntriesCount = (TSize - sizeof(TQueueChunkDerived*)) / sizeof(T);
- static_assert(EntriesCount > 0, "expect EntriesCount > 0");
-
- volatile T Entries[EntriesCount];
- TDerived* volatile Next;
-
- TQueueChunkDerived() {
- memset(this, 0, sizeof(TQueueChunkDerived));
- }
-};
-
-template <typename T, ui32 TSize>
-struct TQueueChunk {
- static const ui32 EntriesCount = (TSize - sizeof(TQueueChunk*)) / sizeof(T);
- static_assert(EntriesCount > 0, "expect EntriesCount > 0");
-
- volatile T Entries[EntriesCount];
- TQueueChunk* volatile Next;
-
- TQueueChunk() {
- memset(this, 0, sizeof(TQueueChunk));
- }
-};
diff --git a/library/cpp/actors/util/queue_oneone_inplace.h b/library/cpp/actors/util/queue_oneone_inplace.h
deleted file mode 100644
index 288011955a..0000000000
--- a/library/cpp/actors/util/queue_oneone_inplace.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include "queue_chunk.h"
-
-template <typename T, ui32 TSize, typename TChunk = TQueueChunk<T, TSize>>
-class TOneOneQueueInplace : TNonCopyable {
- static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::valuer");
-
- TChunk* ReadFrom;
- ui32 ReadPosition;
- ui32 WritePosition;
- TChunk* WriteTo;
-
- friend class TReadIterator;
-
-public:
- class TReadIterator {
- TChunk* ReadFrom;
- ui32 ReadPosition;
-
- public:
- TReadIterator(TChunk* readFrom, ui32 readPosition)
- : ReadFrom(readFrom)
- , ReadPosition(readPosition)
- {
- }
-
- inline T Next() {
- TChunk* head = ReadFrom;
- if (ReadPosition != TChunk::EntriesCount) {
- return AtomicLoad(&head->Entries[ReadPosition++]);
- } else if (TChunk* next = AtomicLoad(&head->Next)) {
- ReadFrom = next;
- ReadPosition = 0;
- return Next();
- }
- return T{};
- }
- };
-
- TOneOneQueueInplace()
- : ReadFrom(new TChunk())
- , ReadPosition(0)
- , WritePosition(0)
- , WriteTo(ReadFrom)
- {
- }
-
- ~TOneOneQueueInplace() {
- Y_DEBUG_ABORT_UNLESS(Head() == 0);
- delete ReadFrom;
- }
-
- struct TPtrCleanDestructor {
- static inline void Destroy(TOneOneQueueInplace<T, TSize>* x) noexcept {
- while (T head = x->Pop())
- delete head;
- delete x;
- }
- };
-
- struct TCleanDestructor {
- static inline void Destroy(TOneOneQueueInplace<T, TSize>* x) noexcept {
- while (x->Pop() != nullptr)
- continue;
- delete x;
- }
- };
-
- struct TPtrCleanInplaceMallocDestructor {
- template <typename TPtrVal>
- static inline void Destroy(TOneOneQueueInplace<TPtrVal*, TSize>* x) noexcept {
- while (TPtrVal* head = x->Pop()) {
- head->~TPtrVal();
- free(head);
- }
- delete x;
- }
- };
-
- void Push(T x) noexcept {
- if (WritePosition != TChunk::EntriesCount) {
- AtomicStore(&WriteTo->Entries[WritePosition], x);
- ++WritePosition;
- } else {
- TChunk* next = new TChunk();
- next->Entries[0] = x;
- AtomicStore(&WriteTo->Next, next);
- WriteTo = next;
- WritePosition = 1;
- }
- }
-
- T Head() {
- TChunk* head = ReadFrom;
- if (ReadPosition != TChunk::EntriesCount) {
- return AtomicLoad(&head->Entries[ReadPosition]);
- } else if (TChunk* next = AtomicLoad(&head->Next)) {
- ReadFrom = next;
- delete head;
- ReadPosition = 0;
- return Head();
- }
- return T{};
- }
-
- T Pop() {
- T ret = Head();
- if (ret)
- ++ReadPosition;
- return ret;
- }
-
- TReadIterator Iterator() {
- return TReadIterator(ReadFrom, ReadPosition);
- }
-};
diff --git a/library/cpp/actors/util/rc_buf.cpp b/library/cpp/actors/util/rc_buf.cpp
deleted file mode 100644
index 946c9846ee..0000000000
--- a/library/cpp/actors/util/rc_buf.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "rc_buf.h"
-
-template<>
-void Out<TRcBuf>(IOutputStream& s, const TRcBuf& x) {
- s.Write(TStringBuf(x));
-}
diff --git a/library/cpp/actors/util/rc_buf.h b/library/cpp/actors/util/rc_buf.h
deleted file mode 100644
index db0f7deff5..0000000000
--- a/library/cpp/actors/util/rc_buf.h
+++ /dev/null
@@ -1,1120 +0,0 @@
-#pragma once
-
-#include <atomic>
-#include <new>
-
-#include <util/generic/ptr.h>
-#include <util/generic/string.h>
-#include <util/generic/hash_set.h>
-#include <util/generic/scope.h>
-#include <util/stream/str.h>
-#include <util/system/sanitizers.h>
-#include <util/system/valgrind.h>
-#include <util/generic/array_ref.h>
-#include <util/system/sys_alloc.h>
-
-#include "shared_data.h"
-#include "rc_buf_backend.h"
-
-#ifdef KIKIMR_TRACE_CONTIGUOUS_DATA_GROW
-#include "shared_data_backtracing_owner.h"
-#endif
-
-namespace NContiguousDataDetails {
- template<typename TContainer>
- struct TContainerTraits {
- static char* UnsafeGetDataMut(const TContainer& backend) {
- return const_cast<char*>(backend.data());
- }
- };
-} // NContiguousDataDetails
-
-class TContiguousSpan
-{
-private:
- const char *Data_ = nullptr;
- size_t Size_ = 0;
-
-public:
- TContiguousSpan() = default;
-
- TContiguousSpan(const char *data, size_t size)
- : Data_(data)
- , Size_(size)
- {}
-
- TContiguousSpan(const TString& str)
- : Data_(str.data())
- , Size_(str.size())
- {}
-
- TContiguousSpan(const TStringBuf& str)
- : Data_(str.data())
- , Size_(str.size())
- {}
-
- TContiguousSpan(const TArrayRef<char>& ref)
- : Data_(ref.data())
- , Size_(ref.size())
- {}
-
- TContiguousSpan(const TArrayRef<const char>& ref)
- : Data_(ref.data())
- , Size_(ref.size())
- {}
-
- TContiguousSpan(const NActors::TSharedData& data)
- : Data_(data.data())
- , Size_(data.size())
- {}
-
- const char& operator[](size_t index) const {
- Y_DEBUG_ABORT_UNLESS(index < Size_);
- return Data_[index];
- }
-
- const char *data() const noexcept {
- return Data_;
- }
-
- size_t size() const noexcept {
- return Size_;
- }
-
- const char *GetData() const noexcept {
- return Data_;
- }
-
- size_t GetSize() const noexcept {
- return Size_;
- }
-
- const char *Data() const noexcept {
- return Data_;
- }
-
- size_t Size() const noexcept {
- return Size_;
- }
-
- TContiguousSpan SubSpan(size_t pos, size_t n) const noexcept {
- pos = Min(pos, size());
- n = Min(n, size() - pos);
- return TContiguousSpan(data() + pos, n);
- }
-
- template<std::size_t Index>
- auto get() const noexcept
- {
- static_assert(Index < 2,
- "Index out of bounds for TContiguousSpan");
- if constexpr (Index == 0) return Data_;
- if constexpr (Index == 1) return Size_;
- }
-
- friend bool operator==(const TContiguousSpan& x, const TContiguousSpan& y) { return Compare(x, y) == 0; }
- friend bool operator!=(const TContiguousSpan& x, const TContiguousSpan& y) { return Compare(x, y) != 0; }
- friend bool operator< (const TContiguousSpan& x, const TContiguousSpan& y) { return Compare(x, y) < 0; }
- friend bool operator<=(const TContiguousSpan& x, const TContiguousSpan& y) { return Compare(x, y) <= 0; }
- friend bool operator> (const TContiguousSpan& x, const TContiguousSpan& y) { return Compare(x, y) > 0; }
- friend bool operator>=(const TContiguousSpan& x, const TContiguousSpan& y) { return Compare(x, y) >= 0; }
-
-private:
- static int Compare(const TContiguousSpan& x, const TContiguousSpan& y) {
- int res = 0;
- if (const size_t common = std::min(x.size(), y.size())) {
- res = std::memcmp(x.data(), y.data(), common);
- }
- return res ? res : x.size() - y.size();
- }
-};
-
-
-
-namespace std
-{
- template<>
- struct tuple_size<::TContiguousSpan>
- : integral_constant<size_t, 2> {};
-
- template<>
- struct tuple_element<0, ::TContiguousSpan>
- {
- using type = const char *;
- };
-
- template<>
- struct tuple_element<1, ::TContiguousSpan>
- {
- using type = size_t;
- };
-}
-
-template <
- class TLeft,
- class TRight,
- typename std::enable_if<std::is_convertible<TLeft,TContiguousSpan>::value>::type* = nullptr,
- typename std::enable_if<std::is_convertible<TRight,TContiguousSpan>::value>::type* = nullptr
- >
-bool operator==(const TLeft& lhs, const TRight& rhs) {
- return TContiguousSpan(lhs) == TContiguousSpan(rhs);
-}
-
-template <
- class TLeft,
- class TRight,
- typename std::enable_if<std::is_convertible<TLeft,TContiguousSpan>::value>::type* = nullptr,
- typename std::enable_if<std::is_convertible<TRight,TContiguousSpan>::value>::type* = nullptr
- >
-bool operator!=(const TLeft& lhs, const TRight& rhs) {
- return TContiguousSpan(lhs) != TContiguousSpan(rhs);
-}
-
-template <
- class TLeft,
- class TRight,
- typename std::enable_if<std::is_convertible<TLeft,TContiguousSpan>::value>::type* = nullptr,
- typename std::enable_if<std::is_convertible<TRight,TContiguousSpan>::value>::type* = nullptr
- >
-bool operator<(const TLeft& lhs, const TRight& rhs) {
- return TContiguousSpan(lhs) < TContiguousSpan(rhs);
-}
-
-template <
- class TLeft,
- class TRight,
- typename std::enable_if<std::is_convertible<TLeft,TContiguousSpan>::value>::type* = nullptr,
- typename std::enable_if<std::is_convertible<TRight,TContiguousSpan>::value>::type* = nullptr
- >
-bool operator<=(const TLeft& lhs, const TRight& rhs) {
- return TContiguousSpan(lhs) <= TContiguousSpan(rhs);
-}
-
-template <
- class TLeft,
- class TRight,
- typename std::enable_if<std::is_convertible<TLeft,TContiguousSpan>::value>::type* = nullptr,
- typename std::enable_if<std::is_convertible<TRight,TContiguousSpan>::value>::type* = nullptr
- >
-bool operator>(const TLeft& lhs, const TRight& rhs) {
- return TContiguousSpan(lhs) > TContiguousSpan(rhs);
-}
-
-template <
- class TLeft,
- class TRight,
- typename std::enable_if<std::is_convertible<TLeft,TContiguousSpan>::value>::type* = nullptr,
- typename std::enable_if<std::is_convertible<TRight,TContiguousSpan>::value>::type* = nullptr
- >
-bool operator>=(const TLeft& lhs, const TRight& rhs) {
- return TContiguousSpan(lhs) >= TContiguousSpan(rhs);
-}
-
-
-class TMutableContiguousSpan
-{
-private:
- char *Data = nullptr;
- size_t Size = 0;
-
-public:
- TMutableContiguousSpan() = default;
-
- TMutableContiguousSpan(char *data, size_t size)
- : Data(data)
- , Size(size)
- {}
-
- char *data() noexcept {
- return Data;
- }
-
- char *GetData() noexcept {
- return Data;
- }
-
- TMutableContiguousSpan SubSpan(size_t pos, size_t n) noexcept {
- pos = Min(pos, size());
- n = Min(n, size() - pos);
- return TMutableContiguousSpan(data() + pos, n);
- }
-
- const char *data() const noexcept {
- return Data;
- }
-
- size_t size() const noexcept {
- return Size;
- }
-
- const char *GetData() const noexcept {
- return Data;
- }
-
- size_t GetSize() const noexcept {
- return Size;
- }
-
- TContiguousSpan SubSpan(size_t pos, size_t n) const noexcept {
- pos = Min(pos, size());
- n = Min(n, size() - pos);
- return TContiguousSpan(data() + pos, n);
- }
-
- operator TContiguousSpan() const noexcept {
- return TContiguousSpan(Data, Size);
- }
-};
-
-struct IContiguousChunk : TThrRefBase {
- using TPtr = TIntrusivePtr<IContiguousChunk>;
-
- virtual ~IContiguousChunk() = default;
-
- /**
- * Should give immutable access to data
- */
- virtual TContiguousSpan GetData() const = 0;
-
- /**
- * Should give mutable access to underlying data
- * If data is shared - data should be copied
- * E.g. for TString str.Detach() should be used
- * Possibly invalidates previous *GetData*() calls
- */
- virtual TMutableContiguousSpan GetDataMut() = 0;
-
- /**
- * Should give mutable access to undelying data as fast as possible
- * Even if data is shared this property should be ignored
- * E.g. in TString const_cast<char *>(str.data()) should be used
- * Possibly invalidates previous *GetData*() calls
- */
- virtual TMutableContiguousSpan UnsafeGetDataMut() {
- return GetDataMut();
- }
-
- /**
- * Should return true if GetDataMut() would not copy contents when called.
- */
- virtual bool IsPrivate() const {
- return true;
- }
-
- virtual size_t GetOccupiedMemorySize() const = 0;
-};
-
-class TRope;
-class TRopeArena;
-
-class TRcBuf {
- friend class TRope;
- friend class TRopeArena;
-
- using TInternalBackend = NDetail::TRcBufInternalBackend;
-
- class TBackend {
- enum class EType : uintptr_t {
- STRING,
- SHARED_DATA,
- INTERNAL_BACKEND,
- EXTERNAL_BACKEND,
- };
-
- struct TBackendHolder {
- uintptr_t Data[2];
- explicit operator bool() const noexcept {
- return Data[0] || Data[1];
- }
- friend bool operator ==(const TBackendHolder& x, const TBackendHolder& y) {
- return x.Data[0] == y.Data[0] && x.Data[1] == y.Data[1];
- }
- };
-
- constexpr static TBackendHolder Empty = {0, 0};
-
-#ifndef TSTRING_IS_STD_STRING
- static_assert(sizeof(TBackendHolder) >= sizeof(TString));
-#endif
- static_assert(sizeof(TBackendHolder) >= sizeof(NActors::TSharedData));
- static_assert(sizeof(TBackendHolder) >= sizeof(TInternalBackend));
-
- TBackendHolder Owner = TBackend::Empty; // lower bits contain type of the owner
-
- public:
- using TCookies = TInternalBackend::TCookies;
-
- static constexpr struct TControlToken {} ControlToken;
- static constexpr size_t CookiesSize = sizeof(TCookies);
-
- TBackend() = default;
-
- TBackend(const TBackend& other)
- : Owner(other.Owner ? Clone(other.Owner) : TBackend::Empty)
- {}
-
- TBackend(TBackend&& other)
- : Owner(std::exchange(other.Owner, TBackend::Empty))
- {}
-
- TBackend(TString s)
- : Owner(Construct<TString>(EType::STRING, std::move(s)))
- {}
-
- TBackend(NActors::TSharedData s)
- : Owner(Construct<NActors::TSharedData>(EType::SHARED_DATA, std::move(s)))
- {}
-
- TBackend(TInternalBackend backend)
- : Owner(Construct<TInternalBackend>(EType::INTERNAL_BACKEND, std::move(backend)))
- {}
-
- TBackend(IContiguousChunk::TPtr backend)
- : Owner(Construct<IContiguousChunk::TPtr>(EType::EXTERNAL_BACKEND, std::move(backend)))
- {}
-
- ~TBackend() {
- if (Owner) {
- Destroy(Owner);
- }
- }
-
- TBackend& operator =(const TBackend& other) {
- if (Y_UNLIKELY(this == &other)) {
- return *this;
- }
-
- if (Owner) {
- Destroy(Owner);
- }
- if (other.Owner) {
- Owner = Clone(other.Owner);
- } else {
- Owner = TBackend::Empty;
- }
- return *this;
- }
-
- TBackend& operator =(TBackend&& other) {
- if (Y_UNLIKELY(this == &other)) {
- return *this;
- }
-
- if (Owner) {
- Destroy(Owner);
- }
- Owner = std::exchange(other.Owner, TBackend::Empty);
- return *this;
- }
-
- bool operator ==(const TBackend& other) const {
- return Owner == other.Owner;
- }
-
- const void *UniqueId() const {
- return reinterpret_cast<const void*>(Owner.Data[0]);
- }
-
- TCookies* GetCookies() {
- if(!Owner) {
- return nullptr;
- }
- return Visit(Owner, [](EType, auto& value) -> TCookies* {
- using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, TInternalBackend>) {
- return value.GetCookies();
- } else {
- return nullptr;
- }
- });
- }
-
- const TCookies* GetCookies() const {
- return const_cast<TBackend&>(*this).GetCookies();
- }
-
- bool IsPrivate() const {
- if(!Owner) {
- return true;
- }
- return Visit(Owner, [](EType, auto& value) -> bool {
- using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, NActors::TSharedData> || std::is_same_v<T, TInternalBackend>) {
- return value.IsPrivate();
- } else if constexpr (std::is_same_v<T, TString>) {
- return value.IsDetached();
- } else if constexpr (std::is_same_v<T, IContiguousChunk::TPtr>) {
- return value.RefCount() == 1 && value->IsPrivate();
- } else {
- static_assert(TDependentFalse<T>);
- }
- });
- }
-
- TContiguousSpan GetData() const {
- if (!Owner) {
- return TContiguousSpan();
- }
- return Visit(Owner, [](EType, auto& value) -> TContiguousSpan {
- using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, TString> || std::is_same_v<T, NActors::TSharedData> || std::is_same_v<T, TInternalBackend>) {
- return {value.data(), value.size()};
- } else if constexpr (std::is_same_v<T, IContiguousChunk::TPtr>) {
- return value->GetData();
- } else {
- static_assert(TDependentFalse<T>, "unexpected type");
- }
- });
- }
-
- TMutableContiguousSpan GetDataMut() {
- if (!Owner) {
- return TMutableContiguousSpan();
- }
- return Visit(Owner, [](EType, auto& value) -> TMutableContiguousSpan {
- using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, TString>) {
- return {value.Detach(), value.size()};
- } else if constexpr (std::is_same_v<T, NActors::TSharedData>) {
- if (value.IsShared()) {
- value = NActors::TSharedData::Copy(value.data(), value.size());
- }
- return {value.mutable_data(), value.size()};
- } else if constexpr (std::is_same_v<T, TInternalBackend>) {
- if (value.IsShared()) {
- value = TInternalBackend::Copy(value.data(), value.size());
- }
- return {value.mutable_data(), value.size()};
- } else if constexpr (std::is_same_v<T, IContiguousChunk::TPtr>) {
- return value->GetDataMut();
- } else {
- static_assert(TDependentFalse<T>, "unexpected type");
- }
- });
- }
-
- TMutableContiguousSpan UnsafeGetDataMut() const {
- if (!Owner) {
- return TMutableContiguousSpan();
- }
- return Visit(Owner, [](EType, auto& value) -> TMutableContiguousSpan {
- using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, TString>) {
- return {const_cast<char*>(value.data()), value.size()};
- } else if constexpr (std::is_same_v<T, NActors::TSharedData> || std::is_same_v<T, TInternalBackend>) {
- return {const_cast<char*>(value.data()), value.size()};
- } else if constexpr (std::is_same_v<T, IContiguousChunk::TPtr>) {
- return value->UnsafeGetDataMut();
- } else {
- static_assert(TDependentFalse<T>, "unexpected type");
- }
- });
- }
-
- size_t GetOccupiedMemorySize() const {
- if (!Owner) {
- return 0;
- }
- 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, NActors::TSharedData> || std::is_same_v<T, TInternalBackend>) {
- return value.size(); // There is no capacity
- } else if constexpr (std::is_same_v<T, IContiguousChunk::TPtr>) {
- return value->GetOccupiedMemorySize();
- } else {
- static_assert(TDependentFalse<T>, "unexpected type");
- }
- });
- }
-
- template <class TType>
- bool ContainsNativeType() const {
- if (!Owner) {
- return false;
- }
- return Visit(Owner, [](EType, auto& value) {
- using T = std::decay_t<decltype(value)>;
- return std::is_same_v<T, TType>;
- });
- }
-
- bool CanGrowFront(const char* begin) const {
- if (!Owner) {
- return false;
- }
- const TCookies* cookies = GetCookies();
- return cookies && (IsPrivate() || cookies->Begin.load() == begin);
- }
-
- bool CanGrowBack(const char* end) const {
- if (!Owner) {
- return false;
- }
- const TCookies* cookies = GetCookies();
- return cookies && (IsPrivate() || cookies->End.load() == end);
- }
-
- void UpdateCookiesUnsafe(const char* contBegin, const char* contEnd) {
- if (!Owner) {
- return;
- }
- TCookies* cookies = GetCookies();
- if (cookies) {
- cookies->Begin.store(contBegin);
- cookies->End.store(contEnd);
- }
- }
-
- bool UpdateCookiesBegin(const char* curBegin, const char* contBegin) {
- if (!Owner) {
- return false;
- }
-
- TCookies* cookies = GetCookies();
- if (cookies) {
- return cookies->Begin.compare_exchange_weak(curBegin, contBegin);
- }
- return false;
- }
-
- bool UpdateCookiesEnd(const char* curEnd, const char* contEnd) {
- if (!Owner) {
- return false;
- }
-
- TCookies* cookies = GetCookies();
- if (cookies) {
- return cookies->End.compare_exchange_weak(curEnd, contEnd);
- }
- return false;
- }
-
- template <typename TResult, typename TCallback>
- std::invoke_result_t<TCallback, const TResult*> ApplySpecificValue(TCallback&& callback) const {
- static_assert(std::is_same_v<TResult, TString> ||
- std::is_same_v<TResult, NActors::TSharedData> ||
- std::is_same_v<TResult, TInternalBackend> ||
- std::is_same_v<TResult, IContiguousChunk::TPtr>);
-
- if (!Owner) {
- return callback(nullptr);
- }
- return Visit(Owner, [&](EType, auto& value) {
- using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, TResult>) {
- return callback(&value);
- } else {
- return callback(nullptr);
- }
- });
- }
-
- explicit operator bool() const {
- return static_cast<bool>(Owner);
- }
-
- 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 TBackendHolder Construct(EType type, TObject&& object) {
- if constexpr (sizeof(TObject) <= sizeof(TBackendHolder)) {
- TBackendHolder res = TBackend::Empty;
- new(&res) std::decay_t<TObject>(std::forward<TObject>(object));
- Y_DEBUG_ABORT_UNLESS((res.Data[0] & ValueMask) == res.Data[0]);
- res.Data[0] = res.Data[0] | static_cast<uintptr_t>(type);
- return res;
- } else {
- return Construct<TObjectHolder<TObject>>(type, TObjectHolder<TObject>(std::forward<TObject>(object)));
- }
- }
-
- template<typename TOwner, typename TCallback, bool IsConst = std::is_const_v<TOwner>>
- static std::invoke_result_t<TCallback, EType, std::conditional_t<IsConst, const TString&, TString&>> VisitRaw(TOwner& origValue, TCallback&& callback) {
- Y_DEBUG_ABORT_UNLESS(origValue);
- const EType type = static_cast<EType>(origValue.Data[0] & TypeMask);
- TBackendHolder value(origValue);
- value.Data[0] = value.Data[0] & ValueMask;
- // bring object type back
- Y_SCOPE_EXIT(&value, &origValue, type){
- if constexpr(!IsConst) {
- value.Data[0] = value.Data[0] | static_cast<uintptr_t>(type);
- origValue = value;
- } else {
- Y_UNUSED(value);
- Y_UNUSED(origValue);
- Y_UNUSED(type);
- }
- };
- 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(TBackendHolder)) {
- return caller(value);
- } else {
- return caller(reinterpret_cast<std::conditional_t<IsConst, const TObjectHolder<T>&, TObjectHolder<T>&>>(value));
- }
- };
- switch (type) {
- case EType::STRING: return wrapper(reinterpret_cast<std::conditional_t<IsConst, const TString&, TString&>>(value));
- case EType::SHARED_DATA: return wrapper(reinterpret_cast<std::conditional_t<IsConst, const NActors::TSharedData&, NActors::TSharedData&>>(value));
- case EType::INTERNAL_BACKEND: return wrapper(reinterpret_cast<std::conditional_t<IsConst, const TInternalBackend&, TInternalBackend&>>(value));
- case EType::EXTERNAL_BACKEND: return wrapper(reinterpret_cast<std::conditional_t<IsConst, const IContiguousChunk::TPtr&, IContiguousChunk::TPtr&>>(value));
- }
- Y_ABORT("Unexpected type# %" PRIu64, static_cast<ui64>(type));
- }
-
- template<typename TOwner, typename TCallback, bool IsConst = std::is_const_v<TOwner>>
- static std::invoke_result_t<TCallback, EType, std::conditional_t<IsConst, const TString&, TString&>> Visit(TOwner& 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; }
- template<typename T> static const T& Unwrap(const TObjectHolder<T>& holder) { return holder.Object->Value; }
-
- template<typename TOwner>
- static TBackendHolder Clone(TOwner& value) {
- return VisitRaw(value, [](EType type, auto& value) { return Construct(type, value); });
- }
-
- template<typename TOwner>
- static void Destroy(TOwner& value) {
- VisitRaw(value, [](EType, auto& value) { CallDtor(value); });
- }
-
- template<typename T>
- static void CallDtor(T& value) {
- value.~T();
- }
- };
-
- static constexpr struct TOwnedPiece {} OwnedPiece{};
-
- TBackend Backend; // who actually holds the data
- const char *Begin; // data start
- const char *End; // data end
-
- explicit TRcBuf(TInternalBackend s, const char *data, size_t size)
- : Backend(std::move(s))
- {
- Y_ABORT_UNLESS(Backend.GetData().data() == nullptr ||
- (Backend.GetCookies() && Backend.GetCookies()->Begin == data && Backend.GetCookies()->End == data + size));
- Begin = data;
- End = data + size;
- }
-
- explicit TRcBuf(TInternalBackend s)
- : Backend(std::move(s))
- {
- auto span = Backend.GetData();
- Begin = span.data();
- End = Begin + span.size();
- }
-
- TRcBuf(TOwnedPiece, const char *data, size_t size, const TRcBuf& from)
- : TRcBuf(from.Backend, {data, size})
- {
- Y_ABORT_UNLESS(data >= from.GetData());
- Y_ABORT_UNLESS(data < from.GetData() + from.GetSize());
- Y_ABORT_UNLESS(data + size <= from.GetData() + from.GetSize());
- Backend.UpdateCookiesUnsafe(Begin, End);
- }
-
- TRcBuf(TOwnedPiece, const char *begin, const char *end, const TRcBuf& from)
- : TRcBuf(OwnedPiece, begin, end - begin, from)
- {}
-
-public:
- static constexpr struct TPiece {} Piece{};
-
- enum class EResizeResult {
- NoAlloc,
- Alloc,
- };
-
- enum class EResizeStrategy {
- KeepRooms,
- FailOnCopy,
- // SaveAllocs, // Move data if there is enough space in (headroom + size + tailroom)
- };
-
- TRcBuf()
- : Begin(nullptr)
- , End(nullptr)
- {}
-
- template<typename T>
- TRcBuf(T&& backend, const TContiguousSpan& data)
- : Backend(std::forward<T>(backend))
- , Begin(data.data())
- , End(Begin + data.size())
- {}
-
- explicit TRcBuf(TString s)
- : Backend(std::move(s))
- {
- auto span = Backend.GetData();
- Begin = span.data();
- End = Begin + span.size();
- }
-
- explicit TRcBuf(NActors::TSharedData s)
- : Backend(std::move(s))
- {
- auto span = Backend.GetData();
- Begin = span.data();
- End = Begin + span.size();
- }
-
- TRcBuf(IContiguousChunk::TPtr backend)
- : TRcBuf(backend, backend->GetData())
- {}
-
- TRcBuf(TPiece, const char *data, size_t size, const TRcBuf& from)
- : TRcBuf(from.Backend, {data, size})
- {
- Y_ABORT_UNLESS(data >= from.GetData());
- Y_ABORT_UNLESS(data < from.GetData() + from.GetSize());
- Y_ABORT_UNLESS(data + size <= from.GetData() + from.GetSize());
- }
-
- TRcBuf(TPiece, const char *begin, const char *end, const TRcBuf& from)
- : TRcBuf(Piece, begin, end - begin, from)
- {}
-
- TRcBuf(const TRcBuf& other)
- : Backend(other.Backend)
- , Begin(other.Begin)
- , End(other.End)
- {}
-
- TRcBuf(TRcBuf&& other)
- : Backend(std::move(other.Backend))
- , Begin(other.Begin)
- , End(other.End)
- {}
-
- TRcBuf& operator =(const TRcBuf&) = default;
- TRcBuf& operator =(TRcBuf&&) = default;
-
- static TRcBuf Uninitialized(size_t size, size_t headroom = 0, size_t tailroom = 0)
- {
- if (size == 0) {
- return TRcBuf();
- }
-
- if (headroom == 0 && tailroom == 0) {
- TInternalBackend res = TInternalBackend::Uninitialized(size);
- return TRcBuf(
- OwnedPiece,
- res.data(),
- res.data() + res.size(),
- TRcBuf(res));
- }
-
- TInternalBackend res = TInternalBackend::Uninitialized(size, headroom, tailroom);
- return TRcBuf(res, res.data() + headroom, size);
- }
-
- static TRcBuf Copy(TContiguousSpan data, size_t headroom = 0, size_t tailroom = 0) {
- TRcBuf res = Uninitialized(data.size(), headroom, tailroom);
- std::memcpy(res.UnsafeGetDataMut(), data.GetData(), data.GetSize());
- return res;
- }
-
- static TRcBuf Copy(const char* data, size_t size, size_t headroom = 0, size_t tailroom = 0) {
- return Copy({data, size}, headroom, tailroom);
- }
-
- template <class TType>
- bool ContainsNativeType() const {
- return Backend.ContainsNativeType<TType>();
- }
-
- bool CanGrowFront() const noexcept {
- return Backend.CanGrowFront(Begin);
- }
-
- bool CanGrowBack() const noexcept {
- return Backend.CanGrowBack(End);
- }
-
- size_t GetSize() const {
- return End - Begin;
- }
-
- size_t Size() const {
- return End - Begin;
- }
-
- size_t GetOccupiedMemorySize() const {
- return Backend.GetOccupiedMemorySize();
- }
-
- const char* GetData() const {
- return Begin;
- }
-
- char* GetDataMut(size_t headroom = 0, size_t tailroom = 0) {
- const TContiguousSpan backendData = Backend.GetData();
- if (IsPrivate() || (backendData.data() == GetData() && backendData.size() == GetSize())) { // if we own container or reference it whole
- const char* oldBegin = backendData.data();
- ptrdiff_t offset = Begin - oldBegin;
- size_t size = GetSize();
- char* newBegin = Backend.GetDataMut().data();
- Begin = newBegin + offset;
- End = Begin + size;
- return newBegin + offset;
- } else { // make a copy of referenced data
- *this = Copy(GetContiguousSpan(), headroom, tailroom);
- return Backend.GetDataMut().data();
- }
- }
-
- char* UnsafeGetDataMut() {
- const char* oldBegin = Backend.GetData().data();
- ptrdiff_t offset = Begin - oldBegin;
- size_t size = GetSize();
- char* newBegin = Backend.UnsafeGetDataMut().data();
- Begin = newBegin + offset;
- End = Begin + size;
- return newBegin + offset;
- }
-
- template <class TResult>
- TResult ExtractUnderlyingContainerOrCopy() const {
- static_assert(std::is_same_v<TResult, TString> ||
- std::is_same_v<TResult, NActors::TSharedData> ||
- std::is_same_v<TResult, TInternalBackend>);
-
- constexpr bool isSharedData = std::is_same_v<TResult, NActors::TSharedData>;
- TResult res;
-
- const bool found = Backend.ApplySpecificValue<TResult>([&](const TResult *raw) {
- if (raw && raw->data() == Begin && (isSharedData ? End <= Begin + raw->size() : End == Begin + raw->size())) {
- if constexpr (isSharedData) {
- raw->TrimBack(size());
- }
- res = TResult(*raw);
- return true;
- }
- return false;
- });
-
- if (!found) {
- res = TResult::Uninitialized(GetSize());
- char* data = NContiguousDataDetails::TContainerTraits<TResult>::UnsafeGetDataMut(res);
- std::memcpy(data, GetData(), GetSize());
- }
-
- return res;
- }
-
- TContiguousSpan GetContiguousSpan() const {
- return {GetData(), GetSize()};
- }
-
- TStringBuf Slice(size_t pos = 0, size_t len = Max<size_t>()) const noexcept {
- pos = Min(pos, size());
- len = Min(len, size() - pos);
- return {const_cast<TRcBuf*>(this)->UnsafeGetDataMut() + pos, len};
- }
-
- explicit operator TStringBuf() const noexcept {
- return Slice();
- }
-
- TMutableContiguousSpan GetContiguousSpanMut() {
- return {GetDataMut(), GetSize()};
- }
-
- TMutableContiguousSpan UnsafeGetContiguousSpanMut() {
- return {UnsafeGetDataMut(), GetSize()};
- }
-
- bool HasBuffer() const {
- return static_cast<bool>(Backend);
- }
-
- size_t size() const {
- return GetSize();
- }
-
- bool empty() const {
- return !static_cast<bool>(Backend);
- }
-
- operator bool() const {
- return !empty();
- }
-
- const char* data() const {
- return GetData();
- }
-
- const char* Data() const {
- return GetData();
- }
-
- const char* begin() const {
- return Begin;
- }
-
- const char* end() const {
- return End;
- }
-
- char& operator[](size_t pos) {
- return UnsafeGetDataMut()[pos];
- }
-
- const char& operator[](size_t pos) const {
- return GetData()[pos];
- }
-
- void reserve(size_t size) {
- ReserveTailroom(size);
- }
-
- void ReserveHeadroom(size_t size) {
- if (Headroom() >= size) {
- return;
- }
- auto newData = TRcBuf::Uninitialized(GetSize(), size, UnsafeTailroom());
- if (auto data = GetData(); data) {
- std::memcpy(newData.UnsafeGetDataMut(), GetData(), GetSize());
- }
- *this = std::move(newData);
- }
-
- void ReserveTailroom(size_t size) {
- if (Tailroom() >= size) {
- return;
- }
- auto newData = TRcBuf::Uninitialized(GetSize(), UnsafeHeadroom(), size);
- if (auto data = GetData(); data) {
- std::memcpy(newData.UnsafeGetDataMut(), GetData(), GetSize());
- }
- *this = std::move(newData);
- }
-
- void ReserveBidi(size_t headroom, size_t tailroom) {
- if (Headroom() >= headroom && Tailroom() >= tailroom) {
- return;
- }
- auto newData = TRcBuf::Uninitialized(
- GetSize(),
- std::max(UnsafeHeadroom(), headroom),
- std::max(UnsafeTailroom(), tailroom));
- if (auto data = GetData(); data) {
- std::memcpy(newData.UnsafeGetDataMut(), GetData(), GetSize());
- }
- *this = std::move(newData);
- }
-
- EResizeResult GrowFront(size_t size, EResizeStrategy strategy = EResizeStrategy::KeepRooms) {
- if (Headroom() >= size && Backend.UpdateCookiesBegin(Begin, Begin - size)) {
- Begin -= size;
- return EResizeResult::NoAlloc;
- } else {
- if (strategy == EResizeStrategy::FailOnCopy && static_cast<bool>(Backend)) {
- Y_ABORT("Fail on grow");
- }
- auto newData = TRcBuf::Uninitialized(size + GetSize(), UnsafeHeadroom() > size ? UnsafeHeadroom() - size : 0, UnsafeTailroom());
- if (auto data = GetData(); data) {
- std::memcpy(newData.UnsafeGetDataMut() + size, GetData(), GetSize());
- }
- *this = std::move(newData);
- return EResizeResult::Alloc;
- }
- }
-
- EResizeResult GrowBack(size_t size, EResizeStrategy strategy = EResizeStrategy::KeepRooms) {
- if (Tailroom() > size && Backend.UpdateCookiesEnd(End, End + size)) {
- End += size;
- return EResizeResult::NoAlloc;
- } else {
- if (strategy == EResizeStrategy::FailOnCopy && static_cast<bool>(Backend)) {
- Y_ABORT("Fail on grow");
- }
- auto newData = TRcBuf::Uninitialized(size + GetSize(), UnsafeHeadroom(), UnsafeTailroom() > size ? UnsafeTailroom() - size : 0);
- if (auto data = GetData(); data) {
- std::memcpy(newData.UnsafeGetDataMut(), GetData(), GetSize());
- }
- *this = std::move(newData);
- return EResizeResult::Alloc;
- }
- }
-
- void TrimBack(size_t size) {
- Y_ABORT_UNLESS(size <= GetSize());
- End = End - (GetSize() - size);
- }
-
- void TrimFront(size_t size) {
- Y_ABORT_UNLESS(size <= GetSize());
- Begin = Begin + (GetSize() - size);
- }
-
- char* Detach() {
- return GetDataMut();
- }
-
- bool IsPrivate() const {
- return Backend.IsPrivate();
- }
-
- size_t UnsafeHeadroom() const {
- return Begin - Backend.GetData().data();
- }
-
- size_t UnsafeTailroom() const {
- auto span = Backend.GetData();
- return (span.GetData() + span.GetSize()) - End;
- }
-
- size_t Headroom() const {
- if (Backend.CanGrowFront(Begin)) {
- return UnsafeHeadroom();
- }
-
- return 0;
- }
-
- size_t Tailroom() const {
- if (Backend.CanGrowBack(End)) {
- return UnsafeTailroom();
- }
-
- return 0;
- }
-
- operator TContiguousSpan() const noexcept {
- return TContiguousSpan(GetData(), GetSize());
- }
-
- explicit operator TMutableContiguousSpan() noexcept {
- return TMutableContiguousSpan(GetDataMut(), GetSize());
- }
-};
diff --git a/library/cpp/actors/util/rc_buf_backend.h b/library/cpp/actors/util/rc_buf_backend.h
deleted file mode 100644
index 9cb8616554..0000000000
--- a/library/cpp/actors/util/rc_buf_backend.h
+++ /dev/null
@@ -1,230 +0,0 @@
-#pragma once
-
-#include <atomic>
-
-#include <library/cpp/deprecated/atomic/atomic.h>
-
-#include <util/system/types.h>
-#include <util/system/compiler.h>
-#include <util/generic/array_ref.h>
-#include <util/system/sys_alloc.h>
-
-namespace NDetail {
-
-struct TRcBufInternalBackend {
-public:
- struct TCookies {
- using TSelf = TCookies;
- std::atomic<const char*> Begin;
- std::atomic<const char*> End;
-
- static size_t BytesToAligned(size_t size) {
- bool misaligned = size % alignof(TSelf);
- return misaligned ? alignof(TSelf) - size % alignof(TSelf) : 0;
- }
-
- static size_t BytesToAlloc(size_t size) {
- return size + BytesToAligned(size) + sizeof(TSelf);
- }
- };
-private:
- // to be binary compatible with TSharedData
- struct THeader : public TCookies {
- TAtomic RefCount;
- ui64 Zero = 0;
- };
-
- enum : size_t {
- HeaderSize = sizeof(THeader),
- OverheadSize = HeaderSize,
- MaxDataSize = (std::numeric_limits<size_t>::max() - OverheadSize)
- };
-
-public:
- TRcBufInternalBackend() noexcept
- : Data_(nullptr)
- , Size_(0)
- { }
-
- ~TRcBufInternalBackend() noexcept {
- Release();
- }
-
- TRcBufInternalBackend(const TRcBufInternalBackend& other) noexcept
- : Data_(other.Data_)
- , Size_(other.Size_)
- {
- AddRef();
- }
-
- TRcBufInternalBackend(TRcBufInternalBackend&& other) noexcept
- : Data_(other.Data_)
- , Size_(other.Size_)
- {
- other.Data_ = nullptr;
- other.Size_ = 0;
- }
-
- TRcBufInternalBackend& operator=(const TRcBufInternalBackend& other) noexcept {
- if (this != &other) {
- Release();
- Data_ = other.Data_;
- Size_ = other.Size_;
- AddRef();
- }
- return *this;
- }
-
- TRcBufInternalBackend& operator=(TRcBufInternalBackend&& other) noexcept {
- if (this != &other) {
- Release();
- Data_ = other.Data_;
- Size_ = other.Size_;
- other.Data_ = nullptr;
- other.Size_ = 0;
- }
- return *this;
- }
-
- Y_FORCE_INLINE explicit operator bool() const { return Size_ > 0; }
-
- Y_FORCE_INLINE char* mutable_data() { return Data(); }
- Y_FORCE_INLINE char* mutable_begin() { return Data(); }
- Y_FORCE_INLINE char* mutable_end() { return Data() + Size_; }
-
- Y_FORCE_INLINE const char* data() const { return Data(); }
- Y_FORCE_INLINE const char* begin() const { return Data(); }
- Y_FORCE_INLINE const char* end() const { return Data() + Size_; }
-
- Y_FORCE_INLINE size_t size() const { return Size_; }
-
- /**
- * Copies data to new allocated buffer if data is shared
- * New container loses original owner
- * Returns pointer to mutable buffer
- */
- char* Detach() {
- if (IsShared()) {
- *this = TRcBufInternalBackend::Copy(data(), size());
- }
- return Data_;
- }
-
- bool IsPrivate() const {
- return Data_ ? IsPrivate(Header()) : true;
- }
-
- bool IsShared() const {
- return !IsPrivate();
- }
-
- TString ToString() const {
- return TString(data(), size());
- }
-
- TCookies* GetCookies() {
- return Header();
- }
-
- /**
- * Attach to pre-allocated data with a preceding THeader
- */
- static TRcBufInternalBackend AttachUnsafe(char* data, size_t size) noexcept {
- TRcBufInternalBackend result;
- result.Data_ = data;
- result.Size_ = size;
- return result;
- }
-
- /**
- * Make uninitialized buffer of the specified size
- */
- static TRcBufInternalBackend Uninitialized(size_t size, size_t headroom = 0, size_t tailroom = 0) {
- size_t fullSize = checkedSum(size, checkedSum(headroom, tailroom));
- return AttachUnsafe(Allocate(size, headroom, tailroom), fullSize);
- }
-
- /**
- * Make a copy of the specified data
- */
- static TRcBufInternalBackend Copy(const void* data, size_t size) {
- TRcBufInternalBackend result = Uninitialized(size);
- if (size) {
- ::memcpy(result.Data(), data, size);
- }
- return result;
- }
-
-private:
- Y_FORCE_INLINE THeader* Header() const noexcept {
- Y_DEBUG_ABORT_UNLESS(Data_);
- return reinterpret_cast<THeader*>(Data_);
- }
-
- Y_FORCE_INLINE char* Data() const noexcept {
- Y_DEBUG_ABORT_UNLESS(Data_);
- return Data_ + OverheadSize;
- }
-
- static bool IsPrivate(THeader* header) noexcept {
- return 1 == AtomicGet(header->RefCount);
- }
-
- void AddRef() noexcept {
- if (Data_) {
- AtomicIncrement(Header()->RefCount);
- }
- }
-
- void Release() noexcept {
- if (Data_) {
- auto* header = Header();
- if (IsPrivate(header) || 0 == AtomicDecrement(header->RefCount)) {
- Deallocate(Data_);
- }
- }
- }
-
-private:
- static size_t checkedSum(size_t a, size_t b) {
- if (a > std::numeric_limits<size_t>::max() - b) {
- throw std::length_error("Allocate size overflow");
- }
- return a + b;
- }
-
- static char* Allocate(size_t size, size_t headroom = 0, size_t tailroom = 0) {
- char* data = nullptr;
- size_t fullSize = checkedSum(size, checkedSum(headroom, tailroom));
- if (fullSize > 0) {
- if (fullSize >= MaxDataSize) {
- throw std::length_error("Allocate size overflow");
- }
- auto allocSize = OverheadSize + fullSize;
- char* raw = reinterpret_cast<char*>(y_allocate(allocSize));
-
- auto* header = reinterpret_cast<THeader*>(raw);
- header->Begin = raw + OverheadSize + headroom;
- header->End = raw + allocSize - tailroom;
- header->RefCount = 1;
-
- data = raw;
- }
-
- return data;
- }
-
- static void Deallocate(char* data) noexcept {
- if (data) {
- char* raw = data;
-
- y_deallocate(raw);
- }
- }
-
-private:
- char* Data_;
- size_t Size_;
-};
-
-} // namespace NDetail
diff --git a/library/cpp/actors/util/rc_buf_ut.cpp b/library/cpp/actors/util/rc_buf_ut.cpp
deleted file mode 100644
index c23e8b68d0..0000000000
--- a/library/cpp/actors/util/rc_buf_ut.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-#include "rc_buf.h"
-#include "ut_helpers.h"
-#include "rope.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/random.h>
-
-Y_UNIT_TEST_SUITE(TRcBuf) {
- Y_UNIT_TEST(TypeSize) {
- UNIT_ASSERT_EQUAL(sizeof(TRcBuf), 4 * sizeof(uintptr_t));
- }
-
- Y_UNIT_TEST(Slice) {
- auto data = TRcBuf::Copy("Hello", 5);
- UNIT_ASSERT_VALUES_EQUAL(TString(TStringBuf(data)), TString("Hello"));
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice()), TString("Hello"));
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice(1)), TString("ello"));
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice(1, 3)), TString("ell"));
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice(1, 100)), TString("ello"));
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice(0, 4)), TString("Hell"));
- }
-
- Y_UNIT_TEST(CrossCompare) {
- TString str = "some very long string";
- const TString constStr(str);
- TStringBuf strbuf = str;
- const TStringBuf constStrbuf = str;
- TContiguousSpan span(str);
- const TContiguousSpan constSpan(str);
- TMutableContiguousSpan mutableSpan(const_cast<char*>(str.data()), str.size());
- const TMutableContiguousSpan constMutableSpan(const_cast<char*>(str.data()), str.size());
- TRcBuf data(str);
- const TRcBuf constData(str);
- TArrayRef<char> arrRef(const_cast<char*>(str.data()), str.size());
- const TArrayRef<char> constArrRef(const_cast<char*>(str.data()), str.size());
- TArrayRef<const char> arrConstRef(const_cast<char*>(str.data()), str.size());
- const TArrayRef<const char> constArrConstRef(const_cast<char*>(str.data()), str.size());
- NActors::TSharedData sharedData = NActors::TSharedData::Copy(str.data(), str.size());
- const NActors::TSharedData constSharedData(sharedData);
-
- Permutate(
- [](auto& arg1, auto& arg2) {
- UNIT_ASSERT(arg1 == arg2);
- },
- str,
- constStr,
- strbuf,
- constStrbuf,
- span,
- constSpan,
- mutableSpan,
- constMutableSpan,
- data,
- constData,
- arrRef,
- constArrRef,
- arrConstRef,
- constArrConstRef,
- sharedData,
- constSharedData);
- }
-
- Y_UNIT_TEST(Detach) {
- TRcBuf data = TRcBuf::Copy(TString("test"));
- TRcBuf data2 = data;
- char* res = data2.Detach();
- UNIT_ASSERT_UNEQUAL(data.GetData(), data2.GetData());
- UNIT_ASSERT_EQUAL(res, data2.GetData());
- UNIT_ASSERT_EQUAL(::memcmp(res, "test", 4), 0);
- UNIT_ASSERT_EQUAL(::memcmp(data.GetData(), "test", 4), 0);
- }
-
- Y_UNIT_TEST(Resize) {
- TRcBuf data = TRcBuf::Uninitialized(10, 20, 30);
- UNIT_ASSERT_EQUAL(data.size(), 10);
- UNIT_ASSERT_EQUAL(data.Headroom(), 20);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 30);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), 60);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), data.size() + data.Headroom() + data.Tailroom());
- data.GrowFront(5);
- UNIT_ASSERT_EQUAL(data.size(), 15);
- UNIT_ASSERT_EQUAL(data.Headroom(), 15);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 30);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), 60);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), data.size() + data.Headroom() + data.Tailroom());
- data.GrowBack(5);
- UNIT_ASSERT_EQUAL(data.size(), 20);
- UNIT_ASSERT_EQUAL(data.Headroom(), 15);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 25);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), 60);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), data.size() + data.Headroom() + data.Tailroom());
- data.GrowFront(21);
- UNIT_ASSERT_EQUAL(data.size(), 41);
- UNIT_ASSERT_EQUAL(data.Headroom(), 0);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 25);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), 66);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), data.size() + data.Headroom() + data.Tailroom());
- data.GrowBack(32);
- UNIT_ASSERT_EQUAL(data.size(), 73);
- UNIT_ASSERT_EQUAL(data.Headroom(), 0);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 0);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), 73);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), data.size() + data.Headroom() + data.Tailroom());
- }
-
- Y_UNIT_TEST(ResizeUnshare) {
- TRcBuf data = TRcBuf::Uninitialized(10, 20, 30);
- TRcBuf otherData(data);
- UNIT_ASSERT_EQUAL(data.data(), otherData.data());
- UNIT_ASSERT_EQUAL(data.size(), 10);
- UNIT_ASSERT_EQUAL(data.Headroom(), 20);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 30);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), 60);
- UNIT_ASSERT_EQUAL(otherData.size(), 10);
- UNIT_ASSERT_EQUAL(otherData.Headroom(), 20);
- UNIT_ASSERT_EQUAL(otherData.Tailroom(), 30);
- UNIT_ASSERT_EQUAL(otherData.GetOccupiedMemorySize(), 60);
- data.GrowFront(5);
- data.GrowBack(5);
- UNIT_ASSERT_EQUAL(data.data() + 5, otherData.data());
- UNIT_ASSERT_EQUAL(data.size(), 20);
- UNIT_ASSERT_EQUAL(data.Headroom(), 15);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 25);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), 60);
- otherData.GrowFront(5);
- UNIT_ASSERT_UNEQUAL(data.data(), otherData.data());
- UNIT_ASSERT_EQUAL(otherData.size(), 15);
- UNIT_ASSERT_EQUAL(otherData.Headroom(), 15);
- UNIT_ASSERT_EQUAL(otherData.Tailroom(), 30);
- UNIT_ASSERT_EQUAL(otherData.GetOccupiedMemorySize(), 60);
- data.TrimBack(15);
- data.TrimFront(10);
- UNIT_ASSERT_EQUAL(data.size(), 10);
- UNIT_ASSERT_EQUAL(data.Headroom(), 20);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 30);
- UNIT_ASSERT_EQUAL(data.GetOccupiedMemorySize(), 60);
- }
-
- Y_UNIT_TEST(Trim) {
- TRcBuf data = TRcBuf::Uninitialized(10, 20, 30);
- TRcBuf otherData(data);
- otherData.TrimBack(5);
- UNIT_ASSERT_EQUAL(data.data(), otherData.data());
- UNIT_ASSERT_EQUAL(otherData.Headroom(), 20);
- UNIT_ASSERT_EQUAL(otherData.Tailroom(), 0);
- TRcBuf otherData2(data);
- otherData2.TrimBack(2);
- otherData2.TrimFront(1);
- UNIT_ASSERT_EQUAL(data.data() + 1, otherData2.data());
- UNIT_ASSERT_EQUAL(otherData2.Headroom(), 0);
- UNIT_ASSERT_EQUAL(otherData2.Tailroom(), 0);
- otherData.TrimBack(2);
- otherData.TrimFront(1);
- UNIT_ASSERT_EQUAL(otherData.data(), otherData2.data());
- data.GrowFront(5);
- data.GrowBack(5);
- UNIT_ASSERT_EQUAL(data.data() + 6, otherData2.data());
- UNIT_ASSERT_EQUAL(data.data() + 6, otherData.data());
- otherData.GrowFront(1);
- UNIT_ASSERT_UNEQUAL(data.data() + 7, otherData.data());
- otherData2.GrowBack(1);
- UNIT_ASSERT_UNEQUAL(data.data() + 6, otherData2.data());
- data = TRcBuf::Uninitialized(10);
- otherData = data;
- data.TrimBack(5);
- UNIT_ASSERT_EQUAL(data.data(), otherData.data());
- UNIT_ASSERT_EQUAL(data.size(), 5);
- }
-
- Y_UNIT_TEST(SliceUnshare) {
- TRcBuf data = TRcBuf::Uninitialized(10, 20, 30);
- TRcBuf otherData(TRcBuf::Piece, data.data() + 1, data.size() - 2, data);
- UNIT_ASSERT_EQUAL(otherData.Headroom(), 0);
- UNIT_ASSERT_EQUAL(otherData.Tailroom(), 0);
- }
-
- Y_UNIT_TEST(Reserve) {
- TRcBuf data = TRcBuf::Copy("test", 4, 5, 6);
- TRcBuf data2 = data;
- data.reserve(1);
- data.ReserveTailroom(6);
- UNIT_ASSERT_EQUAL(data.GetData(), data2.GetData());
- UNIT_ASSERT_EQUAL(data.GetSize(), data2.GetSize());
- UNIT_ASSERT_EQUAL(data.Tailroom(), 6);
- data.ReserveHeadroom(5);
- UNIT_ASSERT_EQUAL(data.GetData(), data2.GetData());
- UNIT_ASSERT_EQUAL(data.GetSize(), data2.GetSize());
- UNIT_ASSERT_EQUAL(data.Headroom(), 5);
- data.ReserveBidi(5, 6);
- UNIT_ASSERT_EQUAL(data.GetData(), data2.GetData());
- UNIT_ASSERT_EQUAL(data.GetSize(), data2.GetSize());
- UNIT_ASSERT_EQUAL(data.Headroom(), 5);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 6);
- data.ReserveHeadroom(6);
- UNIT_ASSERT_EQUAL(data.Headroom(), 6);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 6);
- UNIT_ASSERT_EQUAL(::memcmp(data.GetData(), "test", 4), 0);
- data.ReserveTailroom(7);
- UNIT_ASSERT_EQUAL(data.Headroom(), 6);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 7);
- UNIT_ASSERT_EQUAL(::memcmp(data.GetData(), "test", 4), 0);
- data.ReserveBidi(7, 8);
- UNIT_ASSERT_EQUAL(data.Headroom(), 7);
- UNIT_ASSERT_EQUAL(data.Tailroom(), 8);
- UNIT_ASSERT_EQUAL(::memcmp(data.GetData(), "test", 4), 0);
- }
-}
diff --git a/library/cpp/actors/util/recentwnd.h b/library/cpp/actors/util/recentwnd.h
deleted file mode 100644
index 0f5ee17fa0..0000000000
--- a/library/cpp/actors/util/recentwnd.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-
-#include <util/generic/deque.h>
-
-template <typename TElem,
- template <typename, typename...> class TContainer = TDeque>
-class TRecentWnd {
-public:
- TRecentWnd(ui32 wndSize)
- : MaxWndSize_(wndSize)
- {
- }
-
- void Push(const TElem& elem) {
- if (Window_.size() == MaxWndSize_)
- Window_.erase(Window_.begin());
- Window_.emplace_back(elem);
- }
-
- void Push(TElem&& elem) {
- if (Window_.size() == MaxWndSize_)
- Window_.erase(Window_.begin());
- Window_.emplace_back(std::move(elem));
- }
-
- TElem& Last() {
- return Window_.back();
- }
- const TElem& Last() const {
- return Window_.back();
- }
- bool Full() const {
- return Window_.size() == MaxWndSize_;
- }
- ui64 Size() const {
- return Window_.size();
- }
-
- using const_iterator = typename TContainer<TElem>::const_iterator;
-
- const_iterator begin() {
- return Window_.begin();
- }
- const_iterator end() {
- return Window_.end();
- }
-
- void Reset(ui32 wndSize = 0) {
- Window_.clear();
- if (wndSize != 0) {
- MaxWndSize_ = wndSize;
- }
- }
-
- void ResetWnd(ui32 wndSize) {
- Y_ABORT_UNLESS(wndSize != 0);
- MaxWndSize_ = wndSize;
- if (Window_.size() > MaxWndSize_) {
- Window_.erase(Window_.begin(),
- Window_.begin() + Window_.size() - MaxWndSize_);
- }
- }
-
-private:
- TContainer<TElem> Window_;
- ui32 MaxWndSize_;
-};
diff --git a/library/cpp/actors/util/rope.cpp b/library/cpp/actors/util/rope.cpp
deleted file mode 100644
index 0927774099..0000000000
--- a/library/cpp/actors/util/rope.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "rope.h"
-#include <library/cpp/containers/absl_flat_hash/flat_hash_set.h>
-
-size_t TRope::GetOccupiedMemorySize() const {
- size_t res = 0;
- absl::flat_hash_set<const void*> chunks;
- for (const auto& chunk : Chain) {
- if (const auto [it, inserted] = chunks.insert(chunk.Backend.UniqueId()); inserted) {
- res += chunk.Backend.GetOccupiedMemorySize();
- }
- }
- return res;
-}
diff --git a/library/cpp/actors/util/rope.h b/library/cpp/actors/util/rope.h
deleted file mode 100644
index b092d502cd..0000000000
--- a/library/cpp/actors/util/rope.h
+++ /dev/null
@@ -1,1148 +0,0 @@
-#pragma once
-
-#include <util/generic/ptr.h>
-#include <util/generic/string.h>
-#include <util/generic/hash_set.h>
-#include <util/generic/scope.h>
-#include <util/stream/zerocopy.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_embedded_list.h"
-//#include "rope_cont_list.h"
-//#include "rope_cont_deque.h"
-
-#include "rc_buf.h"
-
-class TRopeAlignedBuffer : public IContiguousChunk {
- 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_ABORT_UNLESS(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_ABORT();
- }
-
- 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);
- }
-
- TContiguousSpan GetData() const override {
- return {Data + Offset, Size};
- }
-
- TMutableContiguousSpan GetDataMut() override {
- return {Data + Offset, Size};
- }
-
- size_t GetOccupiedMemorySize() const override {
- return Capacity;
- }
-
- size_t GetCapacity() const {
- return Capacity;
- }
-
- char *GetBuffer() {
- return Data + Offset;
- }
-};
-
-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;
-
- using TChunkList = NRopeDetails::TChunkList<TRcBuf>;
-
-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_ABORT_UNLESS(ValidityToken == Rope->GetValidityToken());
- Y_ABORT_UNLESS(Iter == Rope->Chain.end() || Iter->Backend);
-#endif
- }
-
- TIteratorImpl& operator +=(size_t amount) {
- CheckValid();
-
- while (amount) {
- Y_DEBUG_ABORT_UNLESS(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_DEBUG_ABORT_UNLESS(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;
- }
-
- template<bool Mut = !IsConst, std::enable_if_t<Mut, bool> = true>
- char *ContiguousDataMut() {
- CheckValid();
- return GetChunk().GetDataMut();
- }
-
- template<bool Mut = !IsConst, std::enable_if_t<Mut, bool> = true>
- char *UnsafeContiguousDataMut() {
- CheckValid();
- return GetChunk().UnsafeGetDataMut();
- }
-
- // 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_DEBUG_ABORT_UNLESS(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_DEBUG_ABORT_UNLESS(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_DEBUG_ABORT_UNLESS(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 TRcBuf& GetChunk() const {
- CheckValid();
- return *Iter;
- }
-
- template<bool Mut = !IsConst, std::enable_if_t<Mut, bool> = true>
- TRcBuf& GetChunk() {
- 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(const TRcBuf& data) {
- if(!data.HasBuffer()) {
- return;
- }
- Size = data.GetSize();
- Chain.PutToEnd(data);
- }
-
- TRope(TRcBuf&& data) {
- if(!data.HasBuffer()) {
- return;
- }
- Size = data.GetSize();
- Chain.PutToEnd(std::move(data));
- }
-
- TRope(TRope&& rope)
- : Chain(std::move(rope.Chain))
- , Size(std::exchange(rope.Size, 0))
- {
- rope.InvalidateIterators();
- }
-
- explicit TRope(TString s) {
- if (s) {
- Size = s.size();
- if (s.capacity() < 32) {
- s.reserve(32);
- }
- Chain.PutToEnd(std::move(s));
- }
- }
-
- explicit TRope(NActors::TSharedData s) {
- Size = s.size();
- Chain.PutToEnd(std::move(s));
- }
-
- TRope(IContiguousChunk::TPtr item) {
- Size = item->GetData().size();
- Chain.PutToEnd(std::move(item));
- }
-
- TRope(TConstIterator begin, TConstIterator end) {
- Y_DEBUG_ABORT_UNLESS(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(TRcBuf::Piece, begin.ContiguousData(), size, begin.GetChunk());
- begin.AdvanceToNextContiguousBlock();
- Size += size;
- }
-
- if (begin != end && end.PointsToChunkMiddle()) {
- Chain.PutToEnd(TRcBuf::Piece, 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;
- }
-
- size_t size() const {
- return Size;
- }
-
- size_t capacity() const {
- return Size;
- }
-
- bool IsEmpty() const {
- return !Size;
- }
-
- bool empty() const {
- return IsEmpty();
- }
-
- 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_ABORT_UNLESS(Size >= num);
- if (num == Size && !*dest) {
- *dest = std::move(*this);
- return;
- }
- Size -= num;
- dest->Size += num;
-
- TChunkList::iterator first = Chain.begin();
-
- if (num >= first->GetSize() && dest->Chain) { // see if we can glue first chunk to the destination rope
- auto& last = dest->Chain.GetLastChunk();
- if (last.Backend == first->Backend && last.End == first->Begin) {
- last.End = first->End;
- num -= first->GetSize();
- first = Chain.Erase(first);
- }
- }
-
- TChunkList::iterator it;
- for (it = first; num && num >= it->GetSize(); ++it) {
- num -= it->GetSize();
- }
- first = dest->Chain.Splice(dest->Chain.end(), Chain, first, it);
-
- if (num) { // still more data to extract
- 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(TRcBuf::Piece, first->Begin, first->Begin + num, *first);
- first->Begin += num;
- }
- }
-
- void Insert(TIterator pos, TRope&& rope) {
- Y_DEBUG_ABORT_UNLESS(this == pos.Rope);
- Y_DEBUG_ABORT_UNLESS(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, TRcBuf::Piece, pos->Begin, pos.Ptr, pos.GetChunk());
- ++pos.Iter;
- pos->Begin = pos.Ptr;
- }
-
- // perform glueing if possible
- TRcBuf *ropeLeft = &rope.Chain.GetFirstChunk();
- TRcBuf *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_DEBUG_ABORT_UNLESS(!rope);
- InvalidateIterators();
- }
-
- void EraseFront(size_t len) {
- Y_DEBUG_ABORT_UNLESS(Size >= len);
- Size -= len;
-
- while (len) {
- Y_DEBUG_ABORT_UNLESS(Chain);
- TRcBuf& 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_DEBUG_ABORT_UNLESS(Size >= len);
- Size -= len;
-
- while (len) {
- Y_DEBUG_ABORT_UNLESS(Chain);
- TRcBuf& 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();
- Y_DEBUG_ABORT_UNLESS(chunk.Backend);
- 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.EraseFront();
- }
- }
- 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();
- }
-
- static int Compare(const TRope& x, const TContiguousSpan& y) {
- TConstIterator xIter = x.Begin();
- const char* yData = y.data();
- size_t yOffset = 0;
- while (xIter.Valid() && yOffset != y.size()) {
- const size_t step = std::min(xIter.ContiguousSize(), y.size() - yOffset);
- if (int res = memcmp(xIter.ContiguousData(), yData + yOffset, step)) {
- return res;
- }
- xIter += step;
- yOffset += step;
- }
- return xIter.Valid() - (yOffset != y.size());
- }
-
- static int Compare(const TContiguousSpan& x, const TRope& y) {
- return -Compare(y, x);
- }
-
- // Use this method carefully -- it may significantly reduce performance when misused.
- TString ConvertToString() const {
- return ExtractUnderlyingContainerOrCopy<TString>();
- }
-
- /**
- * WARN: this method supports extracting only for natively supported types for any other type the data *will* be copied
- */
- template <class TResult>
- TResult ExtractUnderlyingContainerOrCopy() const {
- if (Chain.begin() != Chain.end() && ++Chain.begin() == Chain.end()) {
- return Chain.GetFirstChunk().ExtractUnderlyingContainerOrCopy<TResult>();
- }
-
- const size_t size = GetSize();
- TResult res = TResult::Uninitialized(size);
- char* data = NContiguousDataDetails::TContainerTraits<TResult>::UnsafeGetDataMut(res);
- Begin().ExtractPlainDataAndAdvance(data, size);
- return res;
- }
-
- void clear() {
- Erase(Begin(), End());
- }
-
- bool IsContiguous() const {
- if(Begin() == End() || (++Begin() == End())) {
- return true;
- }
- return false;
- }
-
- void Compact(size_t headroom = 0, size_t tailroom = 0) {
- if(!IsContiguous()) {
- // TODO(innokentii): use better container, when most outer users stop use TString
- TRcBuf res = TRcBuf::Uninitialized(GetSize(), headroom, tailroom);
- Begin().ExtractPlainDataAndAdvance(res.UnsafeGetDataMut(), res.size());
- Erase(Begin(), End());
- Insert(End(), TRope(res));
- }
- }
-
- static TRope Uninitialized(size_t size)
- {
- TRcBuf res = TRcBuf::Uninitialized(size);
- return TRope(res);
- }
-
- /**
- * Compacts data and calls GetData() on undelying container
- * WARN: Will copy if data isn't contiguous
- */
- TContiguousSpan GetContiguousSpan() {
- if(Begin() == End()) {
- return {nullptr, 0};
- }
- Compact();
- return Begin()->GetContiguousSpan();
- }
-
- /**
- * Compacts data and calls GetDataMut() on undelying container
- * WARN: Will copy if data isn't contiguous
- */
- TMutableContiguousSpan GetContiguousSpanMut() {
- if(Begin() == End()) {
- return {nullptr, 0};
- }
- Compact();
- return Begin()->GetContiguousSpanMut();
- }
-
- /**
- * Compacts data and calls UnsafeGetDataMut() on undelying container
- * WARN: Will copy if data isn't contiguous
- * WARN: Even if underlying container is shared - returns reference to its underlying data
- */
- TMutableContiguousSpan UnsafeGetContiguousSpanMut() {
- if(Begin() == End()) {
- return {nullptr, 0};
- }
- Compact();
- return Begin()->UnsafeGetContiguousSpanMut();
- }
-
- TString DebugString() const {
- TStringStream s;
- s << "{Size# " << Size;
- for (const auto& chunk : Chain) {
- const char *data;
- data = chunk.Backend.GetData().data();
- s << " [" << chunk.Begin - data << ", " << chunk.End - data << ")@" << chunk.Backend.UniqueId();
- }
- s << "}";
- return s.Str();
- }
-
- explicit operator TRcBuf() {
- if(GetSize() == 0) {
- return TRcBuf();
- }
- Compact();
- return TRcBuf(Begin().GetChunk());
- }
-
- size_t GetOccupiedMemorySize() const;
-
- 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; }
-
- friend bool operator==(const TRope& x, const TContiguousSpan& y) { return Compare(x, y) == 0; }
- friend bool operator!=(const TRope& x, const TContiguousSpan& y) { return Compare(x, y) != 0; }
- friend bool operator< (const TRope& x, const TContiguousSpan& y) { return Compare(x, y) < 0; }
- friend bool operator<=(const TRope& x, const TContiguousSpan& y) { return Compare(x, y) <= 0; }
- friend bool operator> (const TRope& x, const TContiguousSpan& y) { return Compare(x, y) > 0; }
- friend bool operator>=(const TRope& x, const TContiguousSpan& y) { return Compare(x, y) >= 0; }
-
- friend bool operator==(const TContiguousSpan& x, const TRope& y) { return Compare(x, y) == 0; }
- friend bool operator!=(const TContiguousSpan& x, const TRope& y) { return Compare(x, y) != 0; }
- friend bool operator< (const TContiguousSpan& x, const TRope& y) { return Compare(x, y) < 0; }
- friend bool operator<=(const TContiguousSpan& x, const TRope& y) { return Compare(x, y) <= 0; }
- friend bool operator> (const TContiguousSpan& x, const TRope& y) { return Compare(x, y) > 0; }
- friend bool operator>=(const TContiguousSpan& x, const TRope& y) { return Compare(x, y) >= 0; }
-
- // FIXME(innokentii) temporary hack
- friend bool operator==(const TRope& x, const TRcBuf& y) { return Compare(x, y.GetContiguousSpan()) == 0; }
- friend bool operator!=(const TRope& x, const TRcBuf& y) { return Compare(x, y.GetContiguousSpan()) != 0; }
- friend bool operator< (const TRope& x, const TRcBuf& y) { return Compare(x, y.GetContiguousSpan()) < 0; }
- friend bool operator<=(const TRope& x, const TRcBuf& y) { return Compare(x, y.GetContiguousSpan()) <= 0; }
- friend bool operator> (const TRope& x, const TRcBuf& y) { return Compare(x, y.GetContiguousSpan()) > 0; }
- friend bool operator>=(const TRope& x, const TRcBuf& y) { return Compare(x, y.GetContiguousSpan()) >= 0; }
-
- friend bool operator==(const TRcBuf& x, const TRope& y) { return Compare(x.GetContiguousSpan(), y) == 0; }
- friend bool operator!=(const TRcBuf& x, const TRope& y) { return Compare(x.GetContiguousSpan(), y) != 0; }
- friend bool operator< (const TRcBuf& x, const TRope& y) { return Compare(x.GetContiguousSpan(), y) < 0; }
- friend bool operator<=(const TRcBuf& x, const TRope& y) { return Compare(x.GetContiguousSpan(), y) <= 0; }
- friend bool operator> (const TRcBuf& x, const TRope& y) { return Compare(x.GetContiguousSpan(), y) > 0; }
- friend bool operator>=(const TRcBuf& x, const TRope& y) { return Compare(x.GetContiguousSpan(), y) >= 0; }
-
-
-private:
- void Cut(TIterator begin, TIterator end, TRope *target) {
- // ensure all iterators are belong to us
- Y_DEBUG_ABORT_UNLESS(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 TRcBuf& from, const char *begin, const char *end) {
- if (target) {
- target->Chain.PutToEnd(TRcBuf::Piece, 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) {
- TRcBuf chunkToSplit = begin.GetChunk();
- addBlock(chunkToSplit, 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, TRcBuf::Piece, firstChunkBegin, begin.Ptr, chunkToSplit);
- }
- } 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_DEBUG_ABORT_UNLESS(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<IContiguousChunk>()>;
-
- TAllocateCallback Allocator;
- TRope Arena;
-
-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_DEBUG_ABORT_UNLESS(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;
- }
-};
-
-struct TRopeUtils {
- static void Memset(TRope::TConstIterator dst, char c, size_t size) {
- while (size) {
- Y_DEBUG_ABORT_UNLESS(dst.Valid());
- size_t len = std::min(size, dst.ContiguousSize());
- memset(const_cast<char*>(dst.ContiguousData()), c, len);
- dst += len;
- size -= len;
- }
- }
-
- static void Memcpy(TRope::TConstIterator dst, TRope::TConstIterator src, size_t size) {
- while (size) {
- Y_DEBUG_ABORT_UNLESS(dst.Valid() && src.Valid(),
- "Invalid iterator in memcpy: dst.Valid() - %" PRIu32 ", src.Valid() - %" PRIu32,
- (ui32)dst.Valid(), (ui32)src.Valid());
- size_t len = std::min(size, std::min(dst.ContiguousSize(), src.ContiguousSize()));
- memcpy(const_cast<char*>(dst.ContiguousData()), src.ContiguousData(), len);
- dst += len;
- src += len;
- size -= len;
- }
- }
-
- static void Memcpy(TRope::TConstIterator dst, const char* src, size_t size) {
- while (size) {
- Y_DEBUG_ABORT_UNLESS(dst.Valid());
- size_t len = std::min(size, dst.ContiguousSize());
- memcpy(const_cast<char*>(dst.ContiguousData()), src, len);
- size -= len;
- dst += len;
- src += len;
- }
- }
-
- static void Memcpy(char* dst, TRope::TConstIterator src, size_t size) {
- while (size) {
- Y_DEBUG_ABORT_UNLESS(src.Valid());
- size_t len = std::min(size, src.ContiguousSize());
- memcpy(dst, src.ContiguousData(), len);
- size -= len;
- dst += len;
- src += len;
- }
- }
-
- // copy less or equal to sizeBound bytes, until src is valid
- static size_t SafeMemcpy(char* dst, TRope::TIterator src, size_t sizeBound) {
- size_t origSize = sizeBound;
- while (sizeBound && src.Valid()) {
- size_t len = Min(sizeBound, src.ContiguousSize());
- memcpy(dst, src.ContiguousData(), len);
- sizeBound -= len;
- dst += len;
- src += len;
- }
- return origSize - sizeBound;
- }
-};
-
-template<size_t BLOCK, size_t ALIGN = 16>
-class TRopeSlideView {
- alignas(ALIGN) char Slide[BLOCK]; // use if distance from current point and next chunk is less than BLOCK
- TRope::TIterator Position; // current position at rope
- size_t Size;
- char* Head; // points to data, it might be current rope chunk or Slide
-
-private:
- void FillBlock() {
- size_t chunkSize = Position.ContiguousSize();
- if (chunkSize >= BLOCK) {
- Size = chunkSize;
- Head = const_cast<char*>(Position.ContiguousData());
- } else {
- Size = TRopeUtils::SafeMemcpy(Slide, Position, BLOCK);
- Head = Slide;
- }
- }
-
-public:
- TRopeSlideView(TRope::TIterator position)
- : Position(position)
- {
- FillBlock();
- }
-
- TRopeSlideView(TRope &rope)
- : TRopeSlideView(rope.Begin())
- {}
-
- // if view on slide then copy slide to rope
- void FlushBlock() {
- if (Head == Slide) {
- TRopeUtils::Memcpy(Position, Head, Size);
- }
- }
-
- TRope::TIterator operator+=(size_t amount) {
- Position += amount;
- FillBlock();
- return Position;
- }
-
- TRope::TIterator GetPosition() const {
- return Position;
- }
-
- char* GetHead() const {
- return Head;
- }
-
- ui8* GetUi8Head() const {
- return reinterpret_cast<ui8*>(Head);
- }
-
- size_t ContiguousSize() const {
- return Size;
- }
-
- bool IsOnChunk() const {
- return Head != Slide;
- }
-};
-
-class TRopeZeroCopyInput : public IZeroCopyInput {
- TRope::TConstIterator Iter;
- const char* Data = nullptr;
- size_t Len = 0;
-
-private:
- size_t DoNext(const void** ptr, size_t len) override {
- Y_DEBUG_ABORT_UNLESS(ptr);
- if (Len == 0) {
- if (Iter.Valid()) {
- Data = Iter.ContiguousData();
- Len = Iter.ContiguousSize();
- Y_DEBUG_ABORT_UNLESS(Len);
- Y_DEBUG_ABORT_UNLESS(Data);
- ++Iter;
- } else {
- Data = nullptr;
- }
- }
-
- size_t chunk = std::min(Len, len);
- *ptr = Data;
- Data += chunk;
- Len -= chunk;
- return chunk;
- }
-
-public:
- explicit TRopeZeroCopyInput(TRope::TConstIterator iter)
- : Iter(iter)
- {
- }
-};
-
-inline TRope TRope::CopySpaceOptimized(TRope&& origin, size_t worstRatioPer1k, TRopeArena& arena) {
- TRope res;
- for (TRcBuf& chunk : origin.Chain) {
- size_t ratio = chunk.GetSize() * 1024 / chunk.GetOccupiedMemorySize();
- 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();
- return res;
-}
-
-
-#if defined(WITH_VALGRIND) || defined(_msan_enabled_)
-
-inline void CheckRopeIsDefined(TRope::TConstIterator begin, ui64 size) {
- while (size) {
- ui64 contiguousSize = Min(size, begin.ContiguousSize());
-# if defined(WITH_VALGRIND)
- VALGRIND_CHECK_MEM_IS_DEFINED(begin.ContiguousData(), contiguousSize);
-# endif
-# if defined(_msan_enabled_)
- NSan::CheckMemIsInitialized(begin.ContiguousData(), contiguousSize);
-# endif
- size -= contiguousSize;
- begin += contiguousSize;
- }
-}
-
-# define CHECK_ROPE_IS_DEFINED(begin, size) CheckRopeIsDefined(begin, size)
-
-#else
-
-# define CHECK_ROPE_IS_DEFINED(begin, size) do {} while (false)
-
-#endif
diff --git a/library/cpp/actors/util/rope_cont_embedded_list.h b/library/cpp/actors/util/rope_cont_embedded_list.h
deleted file mode 100644
index 294599538f..0000000000
--- a/library/cpp/actors/util/rope_cont_embedded_list.h
+++ /dev/null
@@ -1,391 +0,0 @@
-#pragma once
-
-#include <util/generic/intrlist.h>
-
-#include <util/random/random.h>
-
-namespace NRopeDetails {
-
-template<typename TChunk>
-class TChunkList {
- struct TItem : TChunk {
- TItem *Next = nullptr;
- TItem *Prev = nullptr;
-#ifndef NDEBUG
- ui64 ValidityToken = RandomNumber<ui64>();
-#endif
-
- template<typename... TArgs> TItem(TArgs&&... args) : TChunk(std::forward<TArgs>(args)...) {}
-
- ~TItem() {
- Invalidate();
- if (IsInUse()) {
- Unlink();
- }
- }
-
- void LinkBefore(TItem *item) {
- Next = item;
- Prev = item->Prev;
- Next->Prev = Prev->Next = this;
- }
-
- void Unlink() {
- Next->Prev = Prev;
- Prev->Next = Next;
- }
-
- bool IsInUse() const {
- return Next != nullptr;
- }
-
- void ClearSingleItem() {
- Y_DEBUG_ABORT_UNLESS(Next == this && Prev == this);
- static_cast<TChunk&>(*this) = {};
- Next = Prev = nullptr;
- }
-
- template<typename... TArgs>
- TItem *PrepareForUse(TArgs&&... args) {
- Y_DEBUG_ABORT_UNLESS(!IsInUse());
- static_cast<TChunk&>(*this) = TChunk(std::forward<TArgs>(args)...);
- Next = Prev = this;
- Invalidate();
- return this;
- }
-
- static void TransferRange(TItem *insertBefore, TItem *first, TItem *last) { // [first, last] -> insertBefore
- first->Prev->Next = last->Next;
- last->Next->Prev = first->Prev;
- first->Prev = insertBefore->Prev;
- last->Next = insertBefore;
- first->Prev->Next = first;
- last->Next->Prev = last;
- }
-
- void Invalidate() {
-#ifndef NDEBUG
- ValidityToken = RandomNumber<ui64>();
-#endif
- }
- };
-
- // There are three possible states for the list:
- // 1. It is empty. Next = Prev = nullptr, TChunk is default-constructed.
- // 2. It contains single item. Next = Prev = &Root, TChunk contains data.
- // 3. It has more than one item. Next and Prev make up a double-linked list starting with Root item; TChunk contains
- // first item.
- // This container scheme leads to the following properties:
- // 1. Deleting first item in the list invalidates iterators to the first two items.
- // 2. Inserting something before the first item also invalidates iterators to the first two items.
- // This happens because Root is always the first element of the list and when inserting before the Root, we have to
- // shift original Root element to the allocated item and replace Root with newly inserted value.
- // This also makes right-to-left traversing more efficient in some cases.
- TItem Root;
-
- template<typename... TArgs>
- TItem *AllocateItem(TArgs&&... args) {
- return Root.IsInUse()
- ? new TItem{std::forward<TArgs>(args)...}
- : Root.PrepareForUse(std::forward<TArgs>(args)...);
- }
-
-private:
- template<bool IsConst>
- class TIterator {
- friend class TChunkList;
-
- using TChunkListType = std::conditional_t<IsConst, const TChunkList, TChunkList>;
- using TItemType = std::conditional_t<IsConst, const TItem, TItem>;
- using TChunkType = std::conditional_t<IsConst, const TChunk, TChunk>;
-
- TChunkListType *Cont = nullptr;
- TItemType *Item = nullptr;
-#ifndef NDEBUG
- ui64 ValidityToken = 0;
-#endif
-
- private:
- TIterator(TChunkListType *cont, TItemType *item)
- : Cont(cont)
- , Item(item)
- {
- UpdateValidityToken();
- }
-
- public:
- TIterator() = default;
-
- template<bool OtherIsConst, typename = std::enable_if_t<OtherIsConst <= IsConst>>
- TIterator(const TIterator<OtherIsConst>& other)
- : Cont(other.Cont)
- , Item(other.Item)
- {
- UpdateValidityToken();
- }
-
- TChunkType& operator *() const {
- CheckValid();
- return *Item;
- }
-
- TChunkType *operator ->() const {
- CheckValid();
- return Item;
- }
-
- TIterator& operator++() {
- CheckValid();
- Y_DEBUG_ABORT_UNLESS(Item);
- Item = Item->Next;
- if (Item == &Cont->Root) {
- Item = nullptr; // make it end
- }
- UpdateValidityToken();
- return *this;
- }
-
- TIterator operator ++(int) {
- TIterator res(*this);
- ++*this;
- return res;
- }
-
- TIterator& operator--() {
- CheckValid();
- if (!Item) {
- Y_DEBUG_ABORT_UNLESS(*Cont);
- Item = Cont->Root.Prev;
- } else {
- Y_DEBUG_ABORT_UNLESS(Item != &Cont->Root);
- Item = Item->Prev;
- }
- UpdateValidityToken();
- return *this;
- }
-
- TIterator operator --(int) {
- TIterator res(*this);
- --*this;
- return res;
- }
-
- friend bool operator ==(const TIterator& x, const TIterator& y) {
- Y_DEBUG_ABORT_UNLESS(x.Cont == y.Cont);
- x.CheckValid();
- y.CheckValid();
- return x.Item == y.Item;
- }
-
- friend bool operator !=(const TIterator& x, const TIterator& y) {
- return !(x == y);
- }
-
- private:
- void CheckValid() const {
-#ifndef NDEBUG
- Y_DEBUG_ABORT_UNLESS(ValidityToken == (Item ? Item->ValidityToken : 0));
- Y_DEBUG_ABORT_UNLESS(Cont && (Item != &Cont->Root || *Cont));
-#endif
- }
-
- void UpdateValidityToken() {
-#ifndef NDEBUG
- ValidityToken = Item ? Item->ValidityToken : 0;
-#endif
- CheckValid();
- }
- };
-
-public:
- using iterator = TIterator<false>;
- using const_iterator = TIterator<true>;
-
-public:
- TChunkList()
- {}
-
- ~TChunkList() {
- Erase(begin(), end());
- Y_DEBUG_ABORT_UNLESS(!*this);
- }
-
- TChunkList(const TChunkList& other) {
- *this = other;
- }
-
- TChunkList(TChunkList&& other) {
- *this = std::move(other);
- }
-
- TChunkList& operator=(const TChunkList& other) {
- if (this != &other) {
- Erase(begin(), end());
- for (const TChunk& chunk : other) {
- PutToEnd(TChunk(chunk));
- }
- }
- return *this;
- }
-
- TChunkList& operator=(TChunkList&& other) {
- if (this != &other) {
- Erase(begin(), end());
- Y_DEBUG_ABORT_UNLESS(!*this);
- if (other.Root.IsInUse()) { // do we have something to move?
- Root.PrepareForUse(std::move(static_cast<TChunk&>(other.Root)));
- if (other.Root.Next != &other.Root) { // does other contain more than one item?
- TItem::TransferRange(&Root, other.Root.Next, other.Root.Prev);
- }
- other.Root.ClearSingleItem();
- }
- }
- 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)...);
- if (item == &Root) {
- // this is the first item, we don't do anything about it
- } else if (pos.Item != &Root) {
- item->LinkBefore(pos.Item ? pos.Item : &Root);
- } else {
- item->LinkBefore(Root.Next);
- std::swap(static_cast<TChunk&>(*item), static_cast<TChunk&>(Root));
- item = &Root;
- Root.Invalidate();
- }
- return {this, item};
- }
-
- iterator Erase(iterator pos) {
- Pop(pos);
- return pos;
- }
-
- iterator Erase(iterator first, iterator last) {
- if (first == last) {
- return last;
- }
- for (;;) {
- if (last == begin()) {
- EraseFront();
- return begin();
- } else if (--last == first) {
- return Erase(last);
- } else {
- last = Erase(last);
- }
- }
- }
-
- void EraseFront() {
- PopFront();
- }
-
- void EraseBack() {
- Y_DEBUG_ABORT_UNLESS(*this);
- if (Root.Prev != &Root) {
- delete Root.Prev;
- } else {
- EraseFront();
- }
- }
-
- // Splice moves elements from the 'from' list in the range [first, last) to *this, inserting them before 'pos'. It
- // returns iterator of the next remaining item in the 'from' list.
- iterator Splice(iterator pos, TChunkList& from, iterator first, iterator last) {
- if (first == last) { // the source range is empty
- return last;
- }
-
- const bool fromBegin = first == from.begin();
- if (fromBegin) { // remember we have to transfer the first item before returning
- ++first;
- }
-
- // 'first' here either equals to 'last' or points to the middle of the 'from' list
-
- const bool toBegin = pos == begin();
- if (toBegin && first != last) {
- // we are inserting item to the begin of the list, so move the first item of the range; it is important here
- // that 'last' iterator doesn't get invalidated
- pos = InsertBefore(begin(), from.Pop(first));
- ++pos;
- }
-
- const auto temp = last;
- if (first != last) {
- --last; // set 'last' pointing to the actual last element of the source range
-
- Y_DEBUG_ABORT_UNLESS(first.Item != &from.Root);
- Y_DEBUG_ABORT_UNLESS(pos.Item != &Root);
-
- TItem* const firstItem = first.Item;
- TItem* const lastItem = last.Item;
- TItem* const posItem = pos.Item ? pos.Item : &Root;
-
- TItem::TransferRange(posItem, firstItem, lastItem);
-
- // adjust 'pos' to point to the first inserted item
- pos = {this, firstItem};
- }
-
- if (fromBegin) {
- InsertBefore(toBegin ? begin() : pos, from.PopFront());
- return from.begin();
- } else {
- return temp;
- }
- }
-
- operator bool() const { return Root.IsInUse(); }
-
- TChunk& GetFirstChunk() { Y_DEBUG_ABORT_UNLESS(*this); return Root; }
- const TChunk& GetFirstChunk() const { Y_DEBUG_ABORT_UNLESS(*this); return Root; }
- TChunk& GetLastChunk() { Y_DEBUG_ABORT_UNLESS(*this); return *Root.Prev; }
-
- iterator begin() { return *this ? iterator(this, &Root) : end(); }
- const_iterator begin() const { return *this ? const_iterator(this, &Root) : end(); }
- iterator end() { return {this, nullptr}; }
- const_iterator end() const { return {this, nullptr}; }
-
-private:
- TChunk Pop(iterator& pos) {
- pos.CheckValid();
- Y_DEBUG_ABORT_UNLESS(pos.Item);
-
- if (pos.Item == &Root) {
- TChunk res = PopFront();
- pos = begin();
- return res;
- } else {
- Y_DEBUG_ABORT_UNLESS(pos != end());
- TItem* const item = pos++.Item;
- TChunk res = std::move(static_cast<TChunk&>(*item));
- delete item;
- return res;
- }
- }
-
- TChunk PopFront() {
- Y_DEBUG_ABORT_UNLESS(*this);
- TChunk res = std::move(static_cast<TChunk&>(Root));
- if (Root.Next != &Root) {
- static_cast<TChunk&>(Root) = std::move(static_cast<TChunk&>(*Root.Next));
- delete Root.Next;
- Root.Invalidate();
- } else {
- Root.ClearSingleItem();
- }
- return res;
- }
-};
-
-} // NRopeDetails
diff --git a/library/cpp/actors/util/rope_ut.cpp b/library/cpp/actors/util/rope_ut.cpp
deleted file mode 100644
index 0ff85d6c59..0000000000
--- a/library/cpp/actors/util/rope_ut.cpp
+++ /dev/null
@@ -1,418 +0,0 @@
-#include "rope.h"
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/random.h>
-#include "ut_helpers.h"
-
-class TRopeStringBackend : public IContiguousChunk {
- TString Buffer;
-
-public:
- TRopeStringBackend(TString buffer)
- : Buffer(std::move(buffer))
- {}
-
- TContiguousSpan GetData() const override {
- return {Buffer.data(), Buffer.size()};
- }
-
- TMutableContiguousSpan GetDataMut() override {
- return {Buffer.Detach(), Buffer.size()};
- }
-
- TMutableContiguousSpan UnsafeGetDataMut() override {
- return {const_cast<char*>(Buffer.data()), Buffer.size()};
- }
-
- size_t GetOccupiedMemorySize() 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(StringCompare) {
- TRope rope = CreateRope(Text, 10);
- UNIT_ASSERT_EQUAL(rope, Text);
- UNIT_ASSERT_EQUAL(Text, rope);
- rope.Erase(rope.Begin() + 10, rope.Begin() + 11);
- UNIT_ASSERT_UNEQUAL(rope, Text);
- UNIT_ASSERT_UNEQUAL(Text, rope);
- TString str("aa");
- rope = TRope(TString("ab"));
- UNIT_ASSERT_LT(str, rope);
- UNIT_ASSERT_GT(rope, str);
- str = TString("aa");
- rope = TRope(TString("a"));
- UNIT_ASSERT_LT(rope, str);
- UNIT_ASSERT_GT(str, rope);
- str = TString("a");
- rope = TRope(TString("aa"));
- UNIT_ASSERT_LT(str, rope);
- UNIT_ASSERT_GT(rope, str);
- }
-
- 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(Compacted) {
- TRope rope = CreateRope(Text, 10);
- UNIT_ASSERT_EQUAL(rope.UnsafeGetContiguousSpanMut(), Text);
- UNIT_ASSERT(rope.IsContiguous());
- }
-
-#ifndef TSTRING_IS_STD_STRING
- Y_UNIT_TEST(ExtractZeroCopy) {
- TString str = Text;
- TRope packed(str);
- TString extracted = packed.ExtractUnderlyingContainerOrCopy<TString>();
- UNIT_ASSERT_EQUAL(str.data(), extracted.data());
- }
-
- Y_UNIT_TEST(ExtractZeroCopySlice) {
- TString str = Text;
- TRope sliced(str);
- sliced.EraseFront(1);
- TString extracted = sliced.ExtractUnderlyingContainerOrCopy<TString>();
- UNIT_ASSERT_UNEQUAL(str.data(), extracted.data());
- TRope sliced2(str);
- sliced2.EraseBack(1);
- TString extracted2 = sliced2.ExtractUnderlyingContainerOrCopy<TString>();
- UNIT_ASSERT_UNEQUAL(str.data(), extracted2.data());
- }
-
- Y_UNIT_TEST(TStringDetach) {
- TRope pf;
- TRope rope;
- TString string = TString(Text.data(), Text.size());
- rope = TRope(string);
- pf = rope;
- pf.GetContiguousSpanMut();
- UNIT_ASSERT(!string.IsDetached());
- rope.GetContiguousSpanMut();
- UNIT_ASSERT(string.IsDetached());
- }
-
- Y_UNIT_TEST(TStringUnsafeShared) {
- TRope pf;
- TRope rope;
- TString string = TString(Text.data(), Text.size());
- rope = TRope(string);
- pf = rope;
- UNIT_ASSERT(pf.IsContiguous());
- UNIT_ASSERT_EQUAL(pf.UnsafeGetContiguousSpanMut().data(), string.data());
- UNIT_ASSERT(!string.IsDetached());
- }
-
- Y_UNIT_TEST(ContiguousDataInterop) {
- TString string = "Some long-long text needed for not sharing data and testing";
- TRcBuf data(string);
- UNIT_ASSERT_EQUAL(data.UnsafeGetDataMut(), &(*string.cbegin()));
- TRope rope(data); // check operator TRope
- UNIT_ASSERT_EQUAL(rope.UnsafeGetContiguousSpanMut().data(), &(*string.cbegin()));
- TRcBuf otherData(rope);
- UNIT_ASSERT_EQUAL(otherData.UnsafeGetDataMut(), &(*string.cbegin()));
- TString extractedBack = otherData.ExtractUnderlyingContainerOrCopy<TString>();
- UNIT_ASSERT_EQUAL(extractedBack.data(), &(*string.cbegin()));
- }
-#endif
- Y_UNIT_TEST(CrossCompare) {
- TString str = "some very long string";
- const TString constStr(str);
- TStringBuf strbuf = str;
- const TStringBuf constStrbuf = str;
- TContiguousSpan span(str);
- const TContiguousSpan constSpan(str);
- TMutableContiguousSpan mutableSpan(const_cast<char*>(str.data()), str.size());
- const TMutableContiguousSpan constMutableSpan(const_cast<char*>(str.data()), str.size());
- TRcBuf data(str);
- const TRcBuf constData(str);
- TArrayRef<char> arrRef(const_cast<char*>(str.data()), str.size());
- const TArrayRef<char> constArrRef(const_cast<char*>(str.data()), str.size());
- TArrayRef<const char> arrConstRef(const_cast<char*>(str.data()), str.size());
- const TArrayRef<const char> constArrConstRef(const_cast<char*>(str.data()), str.size());
- NActors::TSharedData sharedData = NActors::TSharedData::Copy(str.data(), str.size());
- const NActors::TSharedData constSharedData(sharedData);
- TRope rope(str);
- const TRope constRope(str);
-
- Permutate(
- [](auto& arg1, auto& arg2) {
- UNIT_ASSERT(arg1 == arg2);
- },
- str,
- constStr,
- strbuf,
- constStrbuf,
- span,
- constSpan,
- mutableSpan,
- constMutableSpan,
- data,
- constData,
- arrRef,
- constArrRef,
- arrConstRef,
- constArrConstRef,
- sharedData,
- constSharedData,
- rope,
- constRope);
- }
-
- 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;
- size_t remain = rope.GetSize();
- while (const size_t len = Min(step, remain)) {
- TString data = TString::Uninitialized(len);
- rope.ExtractFrontPlain(data.Detach(), data.size());
- UNIT_ASSERT_VALUES_EQUAL(data, buffer.substr(0, len));
- UNIT_ASSERT_VALUES_EQUAL(RopeToString(rope), 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 == y, x == y);
- UNIT_ASSERT_VALUES_EQUAL(x == yRope, x == y);
- UNIT_ASSERT_VALUES_EQUAL(xRope != yRope, x != y);
- UNIT_ASSERT_VALUES_EQUAL(xRope != y, x != y);
- UNIT_ASSERT_VALUES_EQUAL(x != yRope, x != y);
- UNIT_ASSERT_VALUES_EQUAL(xRope < yRope, x < y);
- UNIT_ASSERT_VALUES_EQUAL(xRope < y, x < y);
- UNIT_ASSERT_VALUES_EQUAL(x < yRope, x < y);
- UNIT_ASSERT_VALUES_EQUAL(xRope <= yRope, x <= y);
- UNIT_ASSERT_VALUES_EQUAL(xRope <= y, x <= y);
- UNIT_ASSERT_VALUES_EQUAL(x <= yRope, x <= y);
- UNIT_ASSERT_VALUES_EQUAL(xRope > yRope, x > y);
- UNIT_ASSERT_VALUES_EQUAL(xRope > y, x > y);
- UNIT_ASSERT_VALUES_EQUAL(x > yRope, x > y);
- UNIT_ASSERT_VALUES_EQUAL(xRope >= yRope, x >= y);
- UNIT_ASSERT_VALUES_EQUAL(xRope >= y, x >= y);
- UNIT_ASSERT_VALUES_EQUAL(x >= 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);
- }
- }
- }
-
- Y_UNIT_TEST(RopeZeroCopyInputBasic) {
- TRope rope = CreateRope(Text, 3);
- TRopeZeroCopyInput input(rope.Begin());
-
- TString result;
- TStringOutput output(result);
- TransferData(&input, &output);
- UNIT_ASSERT_EQUAL(result, Text);
- }
-
- Y_UNIT_TEST(RopeZeroCopyInput) {
- TRope rope;
- rope.Insert(rope.End(), TRope{"abc"});
- rope.Insert(rope.End(), TRope{TString{}});
- rope.Insert(rope.End(), TRope{"de"});
- rope.Insert(rope.End(), TRope{TString{}});
- rope.Insert(rope.End(), TRope{TString{}});
- rope.Insert(rope.End(), TRope{"fghi"});
-
- TRopeZeroCopyInput input(rope.Begin());
-
- const char* data = nullptr;
- size_t len;
-
- len = input.Next(&data, 2);
- UNIT_ASSERT_EQUAL("ab", TStringBuf(data, len));
-
- len = input.Next(&data, 3);
- UNIT_ASSERT_EQUAL("c", TStringBuf(data, len));
-
- len = input.Next(&data, 3);
- UNIT_ASSERT_EQUAL("de", TStringBuf(data, len));
-
- len = input.Next(&data);
- UNIT_ASSERT_EQUAL("fghi", TStringBuf(data, len));
-
- len = input.Next(&data);
- UNIT_ASSERT_EQUAL(len, 0);
-
- len = input.Next(&data);
- UNIT_ASSERT_EQUAL(len, 0);
- }
-}
diff --git a/library/cpp/actors/util/shared_data.cpp b/library/cpp/actors/util/shared_data.cpp
deleted file mode 100644
index 51311ce7a3..0000000000
--- a/library/cpp/actors/util/shared_data.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#include "shared_data.h"
-
-#include "memory_tracker.h"
-
-#include <util/system/sys_alloc.h>
-#include <util/system/sanitizers.h>
-
-namespace NActors {
-
- static constexpr char MemoryLabelSharedData[] = "Tablet/TSharedData/Buffers";
-
- char* TSharedData::Allocate(size_t size) {
- char* data = nullptr;
- if (size > 0) {
- if (size >= MaxDataSize) {
- throw std::length_error("Allocate size overflow");
- }
- auto allocSize = OverheadSize + size;
- char* raw = reinterpret_cast<char*>(y_allocate(allocSize));
-
- auto* privateHeader = reinterpret_cast<TPrivateHeader*>(raw);
- privateHeader->AllocSize = allocSize;
- NActors::NMemory::TLabel<MemoryLabelSharedData>::Add(allocSize);
-
- auto* header = reinterpret_cast<THeader*>(raw + PrivateHeaderSize);
- header->RefCount = 1;
- header->Owner = nullptr;
-
- data = raw + OverheadSize;
- NSan::Poison(data, size);
- }
- return data;
- }
-
- void TSharedData::Deallocate(char* data) noexcept {
- if (data) {
- char* raw = data - OverheadSize;
-
- auto* privateHeader = reinterpret_cast<TPrivateHeader*>(raw);
- NActors::NMemory::TLabel<MemoryLabelSharedData>::Sub(privateHeader->AllocSize);
-
- auto* header = reinterpret_cast<THeader*>(raw + PrivateHeaderSize);
- Y_DEBUG_ABORT_UNLESS(header->Owner == nullptr);
-
- y_deallocate(raw);
- }
- }
-
-}
diff --git a/library/cpp/actors/util/shared_data.h b/library/cpp/actors/util/shared_data.h
deleted file mode 100644
index bd9afb00a5..0000000000
--- a/library/cpp/actors/util/shared_data.h
+++ /dev/null
@@ -1,227 +0,0 @@
-#pragma once
-
-#include <library/cpp/deprecated/atomic/atomic.h>
-
-#include <util/system/types.h>
-#include <util/system/compiler.h>
-#include <util/generic/array_ref.h>
-
-namespace NActors {
-
- class TSharedData {
- public:
- class IOwner {
- public:
- virtual ~IOwner() = default;
-
- virtual void Deallocate(char*) noexcept = 0;
- };
-
- struct TPrivateHeader {
- size_t AllocSize;
- size_t Pad;
- };
-
- static_assert(sizeof(TPrivateHeader) == 16, "TPrivateHeader has an unexpected size");
-
- struct THeader {
- TAtomic RefCount;
- IOwner* Owner;
- };
-
- static_assert(sizeof(THeader) == 16, "THeader has an unexpected size");
-
- enum : size_t {
- PrivateHeaderSize = sizeof(TPrivateHeader),
- HeaderSize = sizeof(THeader),
- OverheadSize = PrivateHeaderSize + HeaderSize,
- MaxDataSize = (std::numeric_limits<size_t>::max() - OverheadSize)
- };
-
- public:
- TSharedData() noexcept
- : Data_(nullptr)
- , Size_(0)
- { }
-
- ~TSharedData() noexcept {
- Release();
- }
-
- TSharedData(const TSharedData& other) noexcept
- : Data_(other.Data_)
- , Size_(other.Size_)
- {
- AddRef();
- }
-
- TSharedData(TSharedData&& other) noexcept
- : Data_(other.Data_)
- , Size_(other.Size_)
- {
- other.Data_ = nullptr;
- other.Size_ = 0;
- }
-
- TSharedData& operator=(const TSharedData& other) noexcept {
- if (this != &other) {
- Release();
- Data_ = other.Data_;
- Size_ = other.Size_;
- AddRef();
- }
- return *this;
- }
-
- TSharedData& operator=(TSharedData&& other) noexcept {
- if (this != &other) {
- Release();
- Data_ = other.Data_;
- Size_ = other.Size_;
- other.Data_ = nullptr;
- other.Size_ = 0;
- }
- return *this;
- }
-
- Y_FORCE_INLINE explicit operator bool() const { return Size_ > 0; }
-
- Y_FORCE_INLINE char* mutable_data() { Y_DEBUG_ABORT_UNLESS(IsPrivate()); return Data_; }
- Y_FORCE_INLINE char* mutable_begin() { Y_DEBUG_ABORT_UNLESS(IsPrivate()); return Data_; }
- Y_FORCE_INLINE char* mutable_end() { Y_DEBUG_ABORT_UNLESS(IsPrivate()); return Data_ + Size_; }
-
- Y_FORCE_INLINE const char* data() const { return Data_; }
- Y_FORCE_INLINE const char* begin() const { return Data_; }
- Y_FORCE_INLINE const char* end() const { return Data_ + Size_; }
-
- Y_FORCE_INLINE size_t size() const { return Size_; }
-
- /**
- * Trims data to the specified size
- * Underlying data is not reallocated
- * Returns trimmed amount in bytes
- */
- size_t TrimBack(size_t size) noexcept {
- size_t trimmed = 0;
- if (Size_ > size) {
- trimmed = Size_ - size;
- if (!size) {
- Release();
- Data_ = nullptr;
- }
- Size_ = size;
- }
- return trimmed;
- }
-
- /**
- * Copies data to new allocated buffer if data is shared
- * New container loses original owner
- * Returns pointer to mutable buffer
- */
- char* Detach() {
- if (IsShared()) {
- *this = TSharedData::Copy(data(), size());
- }
- return Data_;
- }
-
- /**
- * Returns a view of underlying data starting with pos and up to len bytes
- */
- TStringBuf Slice(size_t pos = 0, size_t len = -1) const noexcept {
- pos = Min(pos, Size_);
- len = Min(len, Size_ - pos);
- return { Data_ + pos, len };
- }
-
- explicit operator TStringBuf() const noexcept {
- return Slice();
- }
-
- bool IsPrivate() const {
- return Data_ ? IsPrivate(Header()) : true;
- }
-
- bool IsShared() const {
- return !IsPrivate();
- }
-
- TString ToString() const {
- return TString(data(), size());
- }
-
- /**
- * Attach to pre-allocated data with a preceding THeader
- */
- static TSharedData AttachUnsafe(char* data, size_t size) noexcept {
- TSharedData result;
- result.Data_ = data;
- result.Size_ = size;
- return result;
- }
-
- /**
- * Make uninitialized buffer of the specified size
- */
- static TSharedData Uninitialized(size_t size) {
- return AttachUnsafe(Allocate(size), size);
- }
-
- /**
- * Make a copy of the specified data
- */
- static TSharedData Copy(const void* data, size_t size) {
- TSharedData result = Uninitialized(size);
- if (size) {
- ::memcpy(result.Data_, data, size);
- }
- return result;
- }
-
- /**
- * Make a copy of the specified data
- */
- static TSharedData Copy(TArrayRef<const char> data) {
- return Copy(data.data(), data.size());
- }
-
- private:
- Y_FORCE_INLINE THeader* Header() const noexcept {
- Y_DEBUG_ABORT_UNLESS(Data_);
- return reinterpret_cast<THeader*>(Data_ - sizeof(THeader));
- }
-
- static bool IsPrivate(THeader* header) noexcept {
- return 1 == AtomicGet(header->RefCount);
- }
-
- void AddRef() noexcept {
- if (Data_) {
- AtomicIncrement(Header()->RefCount);
- }
- }
-
- void Release() noexcept {
- if (Data_) {
- auto* header = Header();
- if (IsPrivate(header) || 0 == AtomicDecrement(header->RefCount)) {
- if (auto* owner = header->Owner) {
- owner->Deallocate(Data_);
- } else {
- Deallocate(Data_);
- }
- }
- }
- }
-
- private:
- static char* Allocate(size_t size);
- static void Deallocate(char* data) noexcept;
-
- private:
- char* Data_;
- size_t Size_;
- };
-
-}
diff --git a/library/cpp/actors/util/shared_data_backtracing_owner.h b/library/cpp/actors/util/shared_data_backtracing_owner.h
deleted file mode 100644
index ea479d5fd1..0000000000
--- a/library/cpp/actors/util/shared_data_backtracing_owner.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#pragma once
-
-#include <util/system/sys_alloc.h>
-#include <util/system/backtrace.h>
-
-#include "shared_data.h"
-
-class TBackTracingOwner : public NActors::TSharedData::IOwner {
- using THeader = NActors::TSharedData::THeader;
- using TSelf = TBackTracingOwner;
- using IOwner = NActors::TSharedData::IOwner;
-
- static constexpr size_t PrivateHeaderSize = NActors::TSharedData::PrivateHeaderSize;
- static constexpr size_t HeaderSize = NActors::TSharedData::HeaderSize;
- static constexpr size_t OverheadSize = NActors::TSharedData::OverheadSize;
-
- IOwner* RealOwner = nullptr;
- TBackTrace BackTrace;
- const char* Info;
-public:
-
- static constexpr const char* INFO_FROM_SHARED_DATA = "FROM_SHARED_DATA";
- static constexpr const char* INFO_COPIED_STRING = "COPIED_STRING";
- static constexpr const char* INFO_ALLOC_UNINITIALIZED = "ALLOC_UNINITIALIZED";
- static constexpr const char* INFO_ALLOC_UNINIT_ROOMS = "ALLOC_UNINIT_ROOMS";
-
- static char* Allocate(size_t size, const char* info = nullptr) {
- char* raw = reinterpret_cast<char*>(y_allocate(OverheadSize + size));
- THeader* header = reinterpret_cast<THeader*>(raw + PrivateHeaderSize);
- TSelf* btOwner = new TSelf;
- btOwner->BackTrace.Capture();
- btOwner->Info = info;
- header->RefCount = 1;
- header->Owner = btOwner;
- char* data = raw + OverheadSize;
- return data;
- }
-
- static void FakeOwner(const NActors::TSharedData& data, const char* info = nullptr) {
- THeader* header = Header(data);
- if (header) {
- TSelf* btOwner = new TSelf();
- btOwner->BackTrace.Capture();
- btOwner->Info = info;
- if (header->Owner) {
- btOwner->RealOwner = header->Owner;
- }
- header->Owner = btOwner;
- }
- }
-
- static void UnsafePrintBackTrace(NActors::TSharedData& data) {
- THeader* header = Header(data);
- if(header->Owner) {
- TSelf* owner = static_cast<TSelf*>(header->Owner);
- owner->PrintBackTrace();
- }
- }
-
- void Deallocate(char* data) noexcept override {
- if (!RealOwner) {
- char* raw = data - OverheadSize;
- y_deallocate(raw);
- } else {
- RealOwner->Deallocate(data);
- }
-
- delete this;
- }
-
- IOwner* GetRealOwner() const {
- return RealOwner;
- }
-
- void PrintBackTrace() {
- Cerr << "Deallocate TSharedData with info# " << Info << Endl;
- BackTrace.PrintTo(Cerr);
- }
-private:
- static Y_FORCE_INLINE THeader* Header(const NActors::TSharedData& d) noexcept {
- char* data = const_cast<char*>(d.data());
- if (data) {
- return reinterpret_cast<THeader*>(data - HeaderSize);
- } else {
- return nullptr;
- }
- }
-};
diff --git a/library/cpp/actors/util/shared_data_native_rope_backend_ut.cpp b/library/cpp/actors/util/shared_data_native_rope_backend_ut.cpp
deleted file mode 100644
index 4939403454..0000000000
--- a/library/cpp/actors/util/shared_data_native_rope_backend_ut.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-#include <library/cpp/actors/util/rope.h>
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/random.h>
-
-#include "shared_data_rope_backend.h"
-
-namespace NActors {
-
- namespace {
-
- 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) {
- auto str = s.substr(i, len);
- res.Insert(res.End(), TRope(
- TSharedData::Copy(str.data(), str.size())));
- } 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(TRopeSharedDataNativeBackend) {
-
- // Same tests as in TRope but with new CreateRope using TSharedData backend
-
- 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(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);
- }
- }
- }
-
- // Specific TSharedDataRopeBackend tests
-
- Y_UNIT_TEST(RopeOnlyBorrows) {
- TSharedData data = TSharedData::Copy(Text.data(), Text.size());
- {
- TRope rope;
- rope.Insert(rope.End(), TRope(data));
- UNIT_ASSERT(data.IsShared());
- TSharedData dataCopy = data;
- UNIT_ASSERT(dataCopy.IsShared());
- UNIT_ASSERT_EQUAL(dataCopy.data(), data.data());
- rope.Insert(rope.End(), TRope(data));
- rope.Insert(rope.End(), TRope(data));
- dataCopy.TrimBack(10);
- UNIT_ASSERT_EQUAL(rope.GetSize(), data.size() * 3);
- }
- UNIT_ASSERT(data.IsPrivate());
- }
- }
-
-} // namespace NActors
diff --git a/library/cpp/actors/util/shared_data_rope_backend.h b/library/cpp/actors/util/shared_data_rope_backend.h
deleted file mode 100644
index a221ae668b..0000000000
--- a/library/cpp/actors/util/shared_data_rope_backend.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/util/rc_buf.h>
-
-#include "shared_data.h"
-
-namespace NActors {
-
-class TRopeSharedDataBackend : public IContiguousChunk {
- TSharedData Buffer;
-
-public:
- TRopeSharedDataBackend(TSharedData buffer)
- : Buffer(std::move(buffer))
- {}
-
- TContiguousSpan GetData() const override {
- return {Buffer.data(), Buffer.size()};
- }
-
- TMutableContiguousSpan GetDataMut() override {
- if(Buffer.IsShared()) {
- Buffer = TSharedData::Copy(Buffer.data(), Buffer.size());
- }
- return {Buffer.mutable_data(), Buffer.size()};
- }
-
- TMutableContiguousSpan UnsafeGetDataMut() override {
- return {const_cast<char *>(Buffer.data()), Buffer.size()};
- }
-
- bool IsPrivate() const override {
- return Buffer.IsPrivate();
- }
-
- size_t GetOccupiedMemorySize() const override {
- return Buffer.size();
- }
-};
-
-} // namespace NActors
diff --git a/library/cpp/actors/util/shared_data_rope_backend_ut.cpp b/library/cpp/actors/util/shared_data_rope_backend_ut.cpp
deleted file mode 100644
index b2b4e04634..0000000000
--- a/library/cpp/actors/util/shared_data_rope_backend_ut.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-#include <library/cpp/actors/util/rope.h>
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/random.h>
-
-#include "shared_data_rope_backend.h"
-
-namespace NActors {
-
- namespace {
-
- 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) {
- auto str = s.substr(i, len);
- res.Insert(res.End(), TRope(MakeIntrusive<TRopeSharedDataBackend>(
- TSharedData::Copy(str.data(), str.size()))));
- } 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(TRopeSharedDataBackend) {
-
- // Same tests as in TRope but with new CreateRope using TSharedData backend
-
- 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(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);
- }
- }
- }
-
- // Specific TSharedDataRopeBackend tests
-
- Y_UNIT_TEST(RopeOnlyBorrows) {
- TSharedData data = TSharedData::Copy(Text.data(), Text.size());
- {
- TRope rope;
- rope.Insert(rope.End(), TRope(MakeIntrusive<TRopeSharedDataBackend>(data)));
- UNIT_ASSERT(data.IsShared());
- TSharedData dataCopy = data;
- UNIT_ASSERT(dataCopy.IsShared());
- UNIT_ASSERT_EQUAL(dataCopy.data(), data.data());
- rope.Insert(rope.End(), TRope(MakeIntrusive<TRopeSharedDataBackend>(data)));
- rope.Insert(rope.End(), TRope(MakeIntrusive<TRopeSharedDataBackend>(data)));
- dataCopy.TrimBack(10);
- UNIT_ASSERT_EQUAL(rope.GetSize(), data.size() * 3);
- }
- UNIT_ASSERT(data.IsPrivate());
- }
- }
-
-} // namespace NActors
diff --git a/library/cpp/actors/util/shared_data_ut.cpp b/library/cpp/actors/util/shared_data_ut.cpp
deleted file mode 100644
index 2f7dc2ccc8..0000000000
--- a/library/cpp/actors/util/shared_data_ut.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-#include "shared_data.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/generic/hash.h>
-#include <util/generic/deque.h>
-#include <util/system/sys_alloc.h>
-
-namespace NActors {
-
- Y_UNIT_TEST_SUITE(TSharedDataTest) {
-
- Y_UNIT_TEST(BasicBehavior) {
- auto data = TSharedData::Copy("Hello", 5);
- UNIT_ASSERT(data.IsPrivate());
- UNIT_ASSERT(!data.IsShared());
- UNIT_ASSERT_VALUES_EQUAL(data.size(), 5u);
- UNIT_ASSERT_VALUES_EQUAL(data.end() - data.begin(), 5u);
- UNIT_ASSERT_VALUES_EQUAL(data.mutable_end() - data.mutable_begin(), 5u);
- UNIT_ASSERT(data.begin() == data.data());
- UNIT_ASSERT(data.mutable_data() == data.data());
- UNIT_ASSERT(data.mutable_begin() == data.mutable_data());
-
- UNIT_ASSERT_VALUES_EQUAL(data.ToString(), TString("Hello"));
- UNIT_ASSERT_VALUES_EQUAL(::memcmp(data.data(), "Hello", 5), 0);
-
- auto link = data;
- UNIT_ASSERT(!link.IsPrivate());
- UNIT_ASSERT(!data.IsPrivate());
- UNIT_ASSERT(link.IsShared());
- UNIT_ASSERT(data.IsShared());
- UNIT_ASSERT(link.data() == data.data());
- UNIT_ASSERT(link.size() == data.size());
-
- link = { };
- UNIT_ASSERT(link.IsPrivate());
- UNIT_ASSERT(data.IsPrivate());
- UNIT_ASSERT(!link.IsShared());
- UNIT_ASSERT(!data.IsShared());
-
- UNIT_ASSERT_VALUES_EQUAL(TString(TStringBuf(data)), TString("Hello"));
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice()), TString("Hello"));
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice(1)), TString("ello"));
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice(1, 3)), TString("ell"));
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice(1, 100)), TString("ello"));
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice(0, 4)), TString("Hell"));
-
- link = data;
- UNIT_ASSERT(link.data() == data.data());
- UNIT_ASSERT_VALUES_UNEQUAL(link.Detach(), data.data());
- UNIT_ASSERT_EQUAL(data.size(), link.size());
- UNIT_ASSERT_VALUES_EQUAL(TString(data.Slice()), TString(link.Slice()));
- }
-
- Y_UNIT_TEST(TrimBehavior) {
- auto data = TSharedData::Uninitialized(42);
-
- UNIT_ASSERT_VALUES_EQUAL(data.size(), 42u);
- UNIT_ASSERT(data.data() != nullptr);
-
- // Trim to non-zero does not change addresses
- const char* ptr1 = data.data();
- data.TrimBack(31);
- const char* ptr2 = data.data();
-
- UNIT_ASSERT_VALUES_EQUAL(data.size(), 31u);
- UNIT_ASSERT(ptr1 == ptr2);
-
- // Trim to zero releases underlying data
- data.TrimBack(0);
-
- UNIT_ASSERT_VALUES_EQUAL(data.size(), 0u);
- UNIT_ASSERT(data.data() == nullptr);
- }
-
- class TCustomOwner : public TSharedData::IOwner {
- using THeader = TSharedData::THeader;
-
- public:
- TSharedData Allocate(size_t size) {
- char* raw = reinterpret_cast<char*>(y_allocate(sizeof(THeader) + size));
- THeader* header = reinterpret_cast<THeader*>(raw);
- header->RefCount = 1;
- header->Owner = this;
- char* data = raw + sizeof(THeader);
- Y_ABORT_UNLESS(Allocated_.insert(data).second);
- return TSharedData::AttachUnsafe(data, size);
- }
-
- void Deallocate(char* data) noexcept {
- Y_ABORT_UNLESS(Allocated_.erase(data) > 0);
- char* raw = data - sizeof(THeader);
- y_deallocate(raw);
- Deallocated_.push_back(data);
- }
-
- char* NextDeallocated() {
- char* result = nullptr;
- if (Deallocated_) {
- result = Deallocated_.front();
- Deallocated_.pop_front();
- }
- return result;
- }
-
- private:
- THashSet<void*> Allocated_;
- TDeque<char*> Deallocated_;
- };
-
- Y_UNIT_TEST(CustomOwner) {
- TCustomOwner owner;
- const char* ptr;
-
- // Test destructor releases data
- {
- auto data = owner.Allocate(42);
- UNIT_ASSERT_VALUES_EQUAL(data.size(), 42u);
- ptr = data.data();
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
- }
-
- UNIT_ASSERT(owner.NextDeallocated() == ptr);
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
-
- // Test assignment releases data
- {
- auto data = owner.Allocate(42);
- UNIT_ASSERT_VALUES_EQUAL(data.size(), 42u);
- ptr = data.data();
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
- data = { };
- }
-
- UNIT_ASSERT(owner.NextDeallocated() == ptr);
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
-
- // Test copies keep references correctly
- {
- auto data = owner.Allocate(42);
- UNIT_ASSERT_VALUES_EQUAL(data.size(), 42u);
- ptr = data.data();
- auto copy = data;
- UNIT_ASSERT_VALUES_EQUAL(copy.size(), 42u);
- UNIT_ASSERT(copy.data() == ptr);
- data = { };
- UNIT_ASSERT_VALUES_EQUAL(data.size(), 0u);
- UNIT_ASSERT(data.data() == nullptr);
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
- }
-
- UNIT_ASSERT(owner.NextDeallocated() == ptr);
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
-
- // Test assignment releases correct data
- {
- auto data1 = owner.Allocate(42);
- UNIT_ASSERT_VALUES_EQUAL(data1.size(), 42u);
- auto data2 = owner.Allocate(31);
- UNIT_ASSERT_VALUES_EQUAL(data2.size(), 31u);
- ptr = data1.data();
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
- data1 = data2;
- UNIT_ASSERT(owner.NextDeallocated() == ptr);
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
- ptr = data2.data();
- UNIT_ASSERT_VALUES_EQUAL(data1.size(), 31u);
- UNIT_ASSERT(data1.data() == ptr);
- }
-
- UNIT_ASSERT(owner.NextDeallocated() == ptr);
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
-
- // Test moves don't produce dangling references
- {
- auto data = owner.Allocate(42);
- UNIT_ASSERT_VALUES_EQUAL(data.size(), 42u);
- ptr = data.data();
- auto moved = std::move(data);
- UNIT_ASSERT_VALUES_EQUAL(moved.size(), 42u);
- UNIT_ASSERT(moved.data() == ptr);
- UNIT_ASSERT_VALUES_EQUAL(data.size(), 0u);
- UNIT_ASSERT(data.data() == nullptr);
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
- }
-
- UNIT_ASSERT(owner.NextDeallocated() == ptr);
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
-
- // Test Detach copies correctly and doesn't affect owned data
- {
- auto data = owner.Allocate(42);
- auto disowned = data;
- disowned.Detach();
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
- }
-
- UNIT_ASSERT(owner.NextDeallocated() == ptr);
- UNIT_ASSERT(owner.NextDeallocated() == nullptr);
-
- }
-
- }
-
-}
diff --git a/library/cpp/actors/util/should_continue.cpp b/library/cpp/actors/util/should_continue.cpp
deleted file mode 100644
index 258e6a0aff..0000000000
--- a/library/cpp/actors/util/should_continue.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "should_continue.h"
-
-void TProgramShouldContinue::ShouldRestart() {
- AtomicSet(State, Restart);
-}
-
-void TProgramShouldContinue::ShouldStop(int returnCode) {
- AtomicSet(ReturnCode, returnCode);
- AtomicSet(State, Stop);
-}
-
-TProgramShouldContinue::EState TProgramShouldContinue::PollState() {
- return static_cast<EState>(AtomicGet(State));
-}
-
-int TProgramShouldContinue::GetReturnCode() {
- return static_cast<int>(AtomicGet(ReturnCode));
-}
-
-void TProgramShouldContinue::Reset() {
- AtomicSet(ReturnCode, 0);
- AtomicSet(State, Continue);
-}
diff --git a/library/cpp/actors/util/should_continue.h b/library/cpp/actors/util/should_continue.h
deleted file mode 100644
index 76acc40dc4..0000000000
--- a/library/cpp/actors/util/should_continue.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-#include "defs.h"
-
-class TProgramShouldContinue {
-public:
- enum EState {
- Continue,
- Stop,
- Restart,
- };
-
- void ShouldRestart();
- void ShouldStop(int returnCode = 0);
-
- EState PollState();
- int GetReturnCode();
-
- void Reset();
-private:
- TAtomic ReturnCode = 0;
- TAtomic State = Continue;
-};
diff --git a/library/cpp/actors/util/thread.h b/library/cpp/actors/util/thread.h
deleted file mode 100644
index d742c8c585..0000000000
--- a/library/cpp/actors/util/thread.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include <util/generic/strbuf.h>
-#include <util/stream/str.h>
-#include <util/system/execpath.h>
-#include <util/system/thread.h>
-#include <util/system/thread.h>
-#include <time.h>
-
-inline void SetCurrentThreadName(const TString& name,
- const ui32 maxCharsFromProcessName = 8) {
-#if defined(_linux_)
- // linux limits threadname by 15 + \0
-
- TStringBuf procName(GetExecPath());
- procName = procName.RNextTok('/');
- procName = procName.SubStr(0, maxCharsFromProcessName);
-
- TStringStream linuxName;
- linuxName << procName << "." << name;
- TThread::SetCurrentThreadName(linuxName.Str().data());
-#else
- Y_UNUSED(maxCharsFromProcessName);
- TThread::SetCurrentThreadName(name.data());
-#endif
-}
diff --git a/library/cpp/actors/util/thread_load_log.h b/library/cpp/actors/util/thread_load_log.h
deleted file mode 100644
index 132e99a52d..0000000000
--- a/library/cpp/actors/util/thread_load_log.h
+++ /dev/null
@@ -1,363 +0,0 @@
-#pragma once
-
-#include "defs.h"
-
-#include <util/system/types.h>
-
-#include <type_traits>
-#include <algorithm>
-#include <atomic>
-#include <limits>
-#include <queue>
-
-template <ui64 TIME_SLOT_COUNT, ui64 TIME_SLOT_LENGTH_NS = 131'072, typename Type = std::uint8_t>
-class TThreadLoad {
-public:
- using TimeSlotType = Type;
-
-private:
- static constexpr auto TIME_SLOT_MAX_VALUE = std::numeric_limits<TimeSlotType>::max();
- static constexpr ui64 TIME_SLOT_PART_COUNT = TIME_SLOT_MAX_VALUE + 1;
- static constexpr auto TIME_SLOT_PART_LENGTH_NS = TIME_SLOT_LENGTH_NS / TIME_SLOT_PART_COUNT;
-
- template <typename T>
- static void AtomicAddBound(std::atomic<T>& val, i64 inc) {
- if (inc == 0) {
- return;
- }
-
- auto newVal = val.load();
- auto oldVal = newVal;
-
- do {
- static constexpr auto MAX_VALUE = std::numeric_limits<T>::max();
-
- if (oldVal >= MAX_VALUE) {
- return;
- }
- newVal = std::min<i64>(MAX_VALUE, static_cast<i64>(oldVal) + inc);
- } while (!val.compare_exchange_weak(oldVal, newVal));
- }
-
- template <typename T>
- static void AtomicSubBound(std::atomic<T>& val, i64 sub) {
- if (sub == 0) {
- return;
- }
-
- auto newVal = val.load();
- auto oldVal = newVal;
-
- do {
- if (oldVal == 0) {
- return;
- }
- newVal = std::max<i64>(0, static_cast<i64>(oldVal) - sub);
- } while (!val.compare_exchange_weak(oldVal, newVal));
- }
-
- void UpdateCompleteTimeSlots(ui64 firstSlotNumber, ui64 lastSlotNumber, TimeSlotType timeSlotValue) {
- ui32 firstSlotIndex = firstSlotNumber % TIME_SLOT_COUNT;
- ui32 lastSlotIndex = lastSlotNumber % TIME_SLOT_COUNT;
-
- const ui64 firstTimeSlotsPass = firstSlotNumber / TIME_SLOT_COUNT;
- const ui64 lastTimeSlotsPass = lastSlotNumber / TIME_SLOT_COUNT;
-
- if (firstTimeSlotsPass == lastTimeSlotsPass) {
- // first and last time slots are in the same pass
- for (auto slotNumber = firstSlotNumber + 1; slotNumber < lastSlotNumber; ++slotNumber) {
- auto slotIndex = slotNumber % TIME_SLOT_COUNT;
- TimeSlots[slotIndex] = timeSlotValue;
- }
- } else if (firstTimeSlotsPass + 1 == lastTimeSlotsPass) {
- for (auto slotIndex = (firstSlotNumber + 1) % TIME_SLOT_COUNT; firstSlotIndex < slotIndex && slotIndex < TIME_SLOT_COUNT; ++slotIndex) {
- TimeSlots[slotIndex] = timeSlotValue;
- }
- for (auto slotIndex = 0u; slotIndex < lastSlotIndex; ++slotIndex) {
- TimeSlots[slotIndex] = timeSlotValue;
- }
- } else {
- for (auto slotIndex = 0u; slotIndex < TIME_SLOT_COUNT; ++slotIndex) {
- TimeSlots[slotIndex] = timeSlotValue;
- }
- }
- }
-
-public:
- std::atomic<ui64> LastTimeNs;
- std::atomic<TimeSlotType> TimeSlots[TIME_SLOT_COUNT];
- std::atomic<bool> LastRegisteredPeriodIsBusy = false;
-
- explicit TThreadLoad(ui64 timeNs = 0) {
- static_assert(std::is_unsigned<TimeSlotType>::value);
-
- LastTimeNs = timeNs;
- for (size_t i = 0; i < TIME_SLOT_COUNT; ++i) {
- TimeSlots[i] = 0;
- }
- }
-
- static constexpr auto GetTimeSlotCount() {
- return TIME_SLOT_COUNT;
- }
-
- static constexpr auto GetTimeSlotLengthNs() {
- return TIME_SLOT_LENGTH_NS;
- }
-
- static constexpr auto GetTimeSlotPartLengthNs() {
- return TIME_SLOT_PART_LENGTH_NS;
- }
-
- static constexpr auto GetTimeSlotPartCount() {
- return TIME_SLOT_PART_COUNT;
- }
-
- static constexpr auto GetTimeSlotMaxValue() {
- return TIME_SLOT_MAX_VALUE;
- }
-
- static constexpr auto GetTimeWindowLengthNs() {
- return TIME_SLOT_COUNT * TIME_SLOT_LENGTH_NS;
- }
-
- void RegisterBusyPeriod(ui64 timeNs) {
- RegisterBusyPeriod<true>(timeNs, LastTimeNs.load());
- }
-
- template <bool ModifyLastTime>
- void RegisterBusyPeriod(ui64 timeNs, ui64 lastTimeNs) {
- LastRegisteredPeriodIsBusy = true;
-
- if (timeNs < lastTimeNs) {
- // when time goes back, mark all time slots as 'free'
- for (size_t i = 0u; i < TIME_SLOT_COUNT; ++i) {
- TimeSlots[i] = 0;
- }
-
- if (ModifyLastTime) {
- LastTimeNs = timeNs;
- }
-
- return;
- }
-
- // lastTimeNs <= timeNs
- ui64 firstSlotNumber = lastTimeNs / TIME_SLOT_LENGTH_NS;
- ui32 firstSlotIndex = firstSlotNumber % TIME_SLOT_COUNT;
- ui64 lastSlotNumber = timeNs / TIME_SLOT_LENGTH_NS;
- ui32 lastSlotIndex = lastSlotNumber % TIME_SLOT_COUNT;
-
- if (firstSlotNumber == lastSlotNumber) {
- ui32 slotLengthNs = timeNs - lastTimeNs;
- ui32 slotPartsCount = (slotLengthNs + TIME_SLOT_PART_LENGTH_NS - 1) / TIME_SLOT_PART_LENGTH_NS;
- AtomicAddBound(TimeSlots[firstSlotIndex], slotPartsCount);
-
- if (ModifyLastTime) {
- LastTimeNs = timeNs;
- }
- return;
- }
-
- ui32 firstSlotLengthNs = TIME_SLOT_LENGTH_NS - (lastTimeNs % TIME_SLOT_LENGTH_NS);
- ui32 firstSlotPartsCount = (firstSlotLengthNs + TIME_SLOT_PART_LENGTH_NS - 1) / TIME_SLOT_PART_LENGTH_NS;
- ui32 lastSlotLengthNs = timeNs % TIME_SLOT_LENGTH_NS;
- ui32 lastSlotPartsCount = (lastSlotLengthNs + TIME_SLOT_PART_LENGTH_NS - 1) / TIME_SLOT_PART_LENGTH_NS;
-
- // process first time slot
- AtomicAddBound(TimeSlots[firstSlotIndex], firstSlotPartsCount);
-
- // process complete time slots
- UpdateCompleteTimeSlots(firstSlotNumber, lastSlotNumber, TIME_SLOT_MAX_VALUE);
-
- // process last time slot
- AtomicAddBound(TimeSlots[lastSlotIndex], lastSlotPartsCount);
-
- if (ModifyLastTime) {
- LastTimeNs = timeNs;
- }
- }
-
- void RegisterIdlePeriod(ui64 timeNs) {
- LastRegisteredPeriodIsBusy = false;
-
- ui64 lastTimeNs = LastTimeNs.load();
- if (timeNs < lastTimeNs) {
- // when time goes back, mark all time slots as 'busy'
- for (size_t i = 0u; i < TIME_SLOT_COUNT; ++i) {
- TimeSlots[i] = TIME_SLOT_MAX_VALUE;
- }
- LastTimeNs = timeNs;
- return;
- }
-
- // lastTimeNs <= timeNs
- ui64 firstSlotNumber = lastTimeNs / TIME_SLOT_LENGTH_NS;
- ui32 firstSlotIndex = firstSlotNumber % TIME_SLOT_COUNT;
- ui64 lastSlotNumber = timeNs / TIME_SLOT_LENGTH_NS;
- ui32 lastSlotIndex = lastSlotNumber % TIME_SLOT_COUNT;
-
- if (firstSlotNumber == lastSlotNumber) {
- ui32 slotLengthNs = timeNs - lastTimeNs;
- ui32 slotPartsCount = slotLengthNs / TIME_SLOT_PART_LENGTH_NS;
-
- AtomicSubBound(TimeSlots[firstSlotIndex], slotPartsCount);
-
- LastTimeNs = timeNs;
- return;
- }
-
- ui32 firstSlotLengthNs = TIME_SLOT_LENGTH_NS - (lastTimeNs % TIME_SLOT_LENGTH_NS);
- ui32 firstSlotPartsCount = (firstSlotLengthNs + TIME_SLOT_PART_LENGTH_NS - 1) / TIME_SLOT_PART_LENGTH_NS;
- ui32 lastSlotLengthNs = timeNs % TIME_SLOT_LENGTH_NS;
- ui32 lastSlotPartsCount = (lastSlotLengthNs + TIME_SLOT_PART_LENGTH_NS - 1) / TIME_SLOT_PART_LENGTH_NS;
-
- // process first time slot
- AtomicSubBound(TimeSlots[firstSlotIndex], firstSlotPartsCount);
-
- // process complete time slots
- UpdateCompleteTimeSlots(firstSlotNumber, lastSlotNumber, 0);
-
- // process last time slot
- AtomicSubBound(TimeSlots[lastSlotIndex], lastSlotPartsCount);
-
- LastTimeNs = timeNs;
- }
-};
-
-class TMinusOneThreadEstimator {
-private:
- template <typename T, int MaxSize>
- class TArrayQueue {
- public:
- bool empty() const {
- return FrontIndex == -1;
- }
-
- bool full() const {
- return (RearIndex + 1) % MaxSize == FrontIndex;
- }
-
- T& front() {
- return Data[FrontIndex];
- }
-
- bool push(T &&t) {
- if (full()) {
- return false;
- }
-
- if (FrontIndex == -1) {
- FrontIndex = 0;
- }
-
- RearIndex = (RearIndex + 1) % MaxSize;
- Data[RearIndex] = std::move(t);
- return true;
- }
-
- bool pop() {
- if (empty()) {
- return false;
- }
-
- if (FrontIndex == RearIndex) {
- FrontIndex = RearIndex = -1;
- } else {
- FrontIndex = (FrontIndex + 1) % MaxSize;
- }
-
- return true;
- }
-
- private:
- int FrontIndex = -1;
- int RearIndex = -1;
- T Data[MaxSize];
- };
-
-public:
- template <typename T>
- ui64 MaxLatencyIncreaseWithOneLessCpu(T **threadLoads, ui32 threadCount, ui64 timeNs, ui64 periodNs) {
- Y_ABORT_UNLESS(threadCount > 0);
-
- struct TTimeSlotData {
- typename T::TimeSlotType Load;
- ui64 Index;
- };
-
- ui64 lastTimeNs = timeNs;
- for (auto threadIndex = 0u; threadIndex < threadCount; ++threadIndex) {
- if (threadLoads[threadIndex]->LastRegisteredPeriodIsBusy.load()) {
- lastTimeNs = std::min(lastTimeNs, threadLoads[threadIndex]->LastTimeNs.load());
- } else {
- // make interval [lastTimeNs, timeNs] 'busy'
- threadLoads[threadIndex]->template RegisterBusyPeriod<false>(timeNs, threadLoads[threadIndex]->LastTimeNs.load());
- }
- }
-
- periodNs = std::min(T::GetTimeWindowLengthNs(), periodNs);
-
- ui64 beginTimeNs = periodNs < timeNs ? timeNs - periodNs : 0;
-
- ui64 firstSlotNumber = beginTimeNs / T::GetTimeSlotLengthNs();
- ui64 lastSlotNumber = (lastTimeNs + T::GetTimeSlotLengthNs() - 1) / T::GetTimeSlotLengthNs();
-
- ui64 maxTimeSlotShiftCount = 0u;
- TArrayQueue<TTimeSlotData, T::GetTimeSlotCount()> firstThreadLoadDataQueue;
-
- for (auto slotNumber = firstSlotNumber; slotNumber < lastSlotNumber; ++slotNumber) {
- ui64 slotIndex = slotNumber % T::GetTimeSlotCount();
-
- typename T::TimeSlotType firstThreadTimeSlotValue = threadLoads[0]->TimeSlots[slotIndex].load();
-
- // distribute previous load of the first thread by other threads
- auto foundIdleThread = false;
-
- for (auto threadIndex = 1u; threadIndex < threadCount; ++threadIndex) {
- typename T::TimeSlotType thisThreadAvailableTimeSlotLoad = threadLoads[threadIndex]->GetTimeSlotMaxValue() - threadLoads[threadIndex]->TimeSlots[slotIndex].load();
-
- while (!firstThreadLoadDataQueue.empty() && thisThreadAvailableTimeSlotLoad > 0) {
- auto& firstThreadLoadData = firstThreadLoadDataQueue.front();
-
- auto distributedLoad = std::min(thisThreadAvailableTimeSlotLoad, firstThreadLoadData.Load);
-
- thisThreadAvailableTimeSlotLoad -= distributedLoad;
- firstThreadLoadData.Load -= distributedLoad;
-
- if (firstThreadLoadData.Load == 0) {
- auto timeSlotShiftCount = slotIndex - firstThreadLoadData.Index;
- maxTimeSlotShiftCount = std::max(maxTimeSlotShiftCount, timeSlotShiftCount);
- auto res = firstThreadLoadDataQueue.pop();
- Y_ABORT_UNLESS(res);
- }
- }
-
- if (thisThreadAvailableTimeSlotLoad == threadLoads[threadIndex]->GetTimeSlotMaxValue()) {
- foundIdleThread = true;
- }
- }
-
- // distribute current load of the first thread by other threads
- if (firstThreadTimeSlotValue > 0) {
- if (foundIdleThread) {
- // The current load of the first thead can be
- // moved to the idle thread so there is nothing to do
- } else {
- // The current load of the first thread can be later
- // processed by the following time slots of other threads
- auto res = firstThreadLoadDataQueue.push({firstThreadTimeSlotValue, slotIndex});
- Y_ABORT_UNLESS(res);
- }
- }
- }
-
- if (!firstThreadLoadDataQueue.empty()) {
- const auto& timeSlotData = firstThreadLoadDataQueue.front();
- auto timeSlotShiftCount = T::GetTimeSlotCount() - timeSlotData.Index;
- maxTimeSlotShiftCount = std::max(maxTimeSlotShiftCount, timeSlotShiftCount);
- }
-
- return maxTimeSlotShiftCount * T::GetTimeSlotLengthNs();
- }
-};
diff --git a/library/cpp/actors/util/thread_load_log_ut.cpp b/library/cpp/actors/util/thread_load_log_ut.cpp
deleted file mode 100644
index 20e776cff6..0000000000
--- a/library/cpp/actors/util/thread_load_log_ut.cpp
+++ /dev/null
@@ -1,966 +0,0 @@
-#include "thread_load_log.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <util/random/random.h>
-#include <util/system/hp_timer.h>
-#include <util/system/thread.h>
-#include <util/system/types.h>
-#include <util/system/sanitizers.h>
-
-#include <limits>
-
-Y_UNIT_TEST_SUITE(ThreadLoadLog) {
-
- Y_UNIT_TEST(TThreadLoad8BitSlotType) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
-
- using TSlotType = std::uint8_t;
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, TSlotType>;
-
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeWindowLengthNs(), timeWindowLengthNs);
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotLengthNs(), timeSlotLengthNs);
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotCount(), timeSlotCount);
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotMaxValue(), std::numeric_limits<TSlotType>::max());
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotPartCount(), (ui64)std::numeric_limits<TSlotType>::max() + 1);
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotPartLengthNs(), T::GetTimeSlotLengthNs() / T::GetTimeSlotPartCount());
- }
-
- Y_UNIT_TEST(TThreadLoad16BitSlotType) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
-
- using TSlotType = std::uint16_t;
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, TSlotType>;
-
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeWindowLengthNs(), timeWindowLengthNs);
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotLengthNs(), timeSlotLengthNs);
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotCount(), timeSlotCount);
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotMaxValue(), std::numeric_limits<TSlotType>::max());
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotPartCount(), (ui64)std::numeric_limits<TSlotType>::max() + 1);
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotPartLengthNs(), T::GetTimeSlotLengthNs() / T::GetTimeSlotPartCount());
- }
-
- Y_UNIT_TEST(TThreadLoad8BitSlotTypeWindowBusy) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
-
- using TSlotType = std::uint8_t;
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, TSlotType>;
-
- T threadLoad;
- threadLoad.RegisterBusyPeriod(T::GetTimeWindowLengthNs());
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), T::GetTimeWindowLengthNs());
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), T::GetTimeSlotMaxValue());
- }
- }
-
- Y_UNIT_TEST(TThreadLoad16BitSlotTypeWindowBusy) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
-
- using TSlotType = std::uint16_t;
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, TSlotType>;
-
- T threadLoad;
- threadLoad.RegisterBusyPeriod(T::GetTimeWindowLengthNs());
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), T::GetTimeWindowLengthNs());
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), T::GetTimeSlotMaxValue());
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterBusyPeriodFirstTimeSlot1) {
- TThreadLoad<38400> threadLoad;
-
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = threadLoad.GetTimeSlotLengthNs() - 1;
- threadLoad.RegisterBusyPeriod(timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
-
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterBusyPeriodFirstTimeSlot2) {
- using T = TThreadLoad<38400>;
-
- ui32 startNs = 2 * T::GetTimeSlotPartLengthNs();
- T threadLoad(startNs);
-
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = 3 * T::GetTimeSlotPartLengthNs() - 1;
- threadLoad.RegisterBusyPeriod(timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 1);
-
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterBusyPeriodFirstTimeSlot3) {
- TThreadLoad<38400> threadLoad;
-
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
-
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterBusyPeriodFirstTimeSlot4) {
- using T = TThreadLoad<38400>;
-
- ui32 startNs = 2 * T::GetTimeSlotPartLengthNs();
- T threadLoad(startNs);
-
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = 3 * T::GetTimeSlotPartLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), (timeNs - startNs) / T::GetTimeSlotPartLengthNs());
-
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterBusyPeriodFirstTwoTimeSlots1) {
- TThreadLoad<38400> threadLoad;
-
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = 2 * threadLoad.GetTimeSlotLengthNs() - 1;
- threadLoad.RegisterBusyPeriod(timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), threadLoad.GetTimeSlotMaxValue());
-
- for (auto slotIndex = 2u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterBusyPeriodFirstTwoTimeSlots2) {
- TThreadLoad<38400> threadLoad;
-
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = 2 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
-
- for (auto slotIndex = 2u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterBusyPeriodFirstThreeTimeSlots1) {
- TThreadLoad<38400> threadLoad;
-
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = 3 * threadLoad.GetTimeSlotLengthNs() - 1;
- threadLoad.RegisterBusyPeriod(timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[2].load(), threadLoad.GetTimeSlotMaxValue());
-
- for (auto slotIndex = 3u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterBusyPeriodFirstThreeTimeSlots2) {
- TThreadLoad<38400> threadLoad;
-
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = 3 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[2].load(), threadLoad.GetTimeSlotMaxValue());
-
- for (auto slotIndex = 3u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterBusyPeriodFirstThreeTimeSlots3) {
- using T = TThreadLoad<38400>;
-
- ui32 startNs = 3 * T::GetTimeSlotPartLengthNs();
- T threadLoad(startNs);
-
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = 0;
- threadLoad.RegisterBusyPeriod(timeNs);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstTimeSlot1) {
- using T = TThreadLoad<38400>;
-
- ui64 timeNs = T::GetTimeSlotPartLengthNs();
- T threadLoad(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 2 * T::GetTimeSlotPartLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 1);
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 3 * T::GetTimeSlotPartLengthNs();
- threadLoad.RegisterIdlePeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 0);
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 4 * T::GetTimeSlotPartLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 1);
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstTimeSlot2) {
- using T = TThreadLoad<38400>;
-
- ui64 timeNs = T::GetTimeSlotPartLengthNs();
- T threadLoad(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 2 * T::GetTimeSlotPartLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 1);
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 3 * T::GetTimeSlotPartLengthNs() - 1;
- threadLoad.RegisterIdlePeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 1);
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 4 * T::GetTimeSlotPartLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 3);
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstTimeSlot3) {
- using T = TThreadLoad<38400>;
-
- ui64 timeNs = T::GetTimeSlotPartLengthNs();
- T threadLoad(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 2 * T::GetTimeSlotPartLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 1);
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 3 * T::GetTimeSlotPartLengthNs() - 1;
- threadLoad.RegisterIdlePeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 1);
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 4 * T::GetTimeSlotPartLengthNs() - 2;
- threadLoad.RegisterIdlePeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 1);
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 5 * T::GetTimeSlotPartLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 3);
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstTwoTimeSlots1) {
- using T = TThreadLoad<38400>;
-
- T threadLoad;
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), 0);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterIdlePeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 2 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 0);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), threadLoad.GetTimeSlotMaxValue());
- for (auto slotIndex = 2u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstTwoTimeSlots2) {
- using T = TThreadLoad<38400>;
-
- T threadLoad;
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), 0);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = threadLoad.GetTimeSlotLengthNs() - 1;
- threadLoad.RegisterIdlePeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 2 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 1);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), threadLoad.GetTimeSlotMaxValue());
- for (auto slotIndex = 2u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstTwoTimeSlots3) {
- using T = TThreadLoad<38400>;
-
- T threadLoad;
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), 0);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = threadLoad.GetTimeSlotLengthNs() - 1;
- threadLoad.RegisterIdlePeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = 2 * threadLoad.GetTimeSlotLengthNs() - 1;
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 1);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), threadLoad.GetTimeSlotMaxValue());
- for (auto slotIndex = 2u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstThreeTimeSlots1) {
- using T = TThreadLoad<38400>;
-
- T threadLoad;
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), 0);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- timeNs = 2 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterIdlePeriod(timeNs);
-
- timeNs = 3 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), 0);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[2].load(), threadLoad.GetTimeSlotMaxValue());
- for (auto slotIndex = 3u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstThreeTimeSlots2) {
- using T = TThreadLoad<38400>;
-
- T threadLoad;
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), 0);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- timeNs = 3 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterIdlePeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
- for (auto slotIndex = 1u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstThreeTimeSlots3) {
- using T = TThreadLoad<38400>;
-
- T threadLoad;
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), 0);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterIdlePeriod(timeNs);
-
- timeNs = 3 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 0);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[2].load(), threadLoad.GetTimeSlotMaxValue());
- for (auto slotIndex = 3u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstThreeTimeSlots4) {
- using T = TThreadLoad<38400>;
-
- T threadLoad;
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), 0);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = threadLoad.GetTimeSlotLengthNs() + 2 * threadLoad.GetTimeSlotPartLengthNs();
- threadLoad.RegisterIdlePeriod(timeNs);
-
- timeNs = 3 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 0);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), threadLoad.GetTimeSlotPartCount() - 2);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[2].load(), threadLoad.GetTimeSlotMaxValue());
- for (auto slotIndex = 3u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodFirstThreeTimeSlots5) {
- using T = TThreadLoad<38400>;
-
- T threadLoad;
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), 0);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = 2 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), threadLoad.GetTimeSlotMaxValue());
- for (auto slotIndex = 2u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = timeNs + threadLoad.GetTimeWindowLengthNs() + threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterIdlePeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(TThreadLoadRegisterIdlePeriodOverTimeWindow) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
-
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, std::uint8_t>;
-
- T threadLoad;
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), 0);
- for (auto slotIndex = 0u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- ui64 timeNs = 5 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[2].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[3].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[4].load(), threadLoad.GetTimeSlotMaxValue());
- for (auto slotIndex = 5u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
-
- timeNs = timeNs + threadLoad.GetTimeWindowLengthNs() - 3 * threadLoad.GetTimeSlotLengthNs();
- threadLoad.RegisterIdlePeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.LastTimeNs.load(), timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[0].load(), 0);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[1].load(), 0);
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[2].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[3].load(), threadLoad.GetTimeSlotMaxValue());
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[4].load(), threadLoad.GetTimeSlotMaxValue());
- for (auto slotIndex = 5u; slotIndex < threadLoad.GetTimeSlotCount(); ++slotIndex) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoad.TimeSlots[slotIndex].load(), 0);
- }
- }
-
- Y_UNIT_TEST(MinusOneThreadEstimatorTwoThreadLoadsZeroShiftNs) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
-
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, std::uint16_t>;
-
- UNIT_ASSERT_VALUES_EQUAL(T::GetTimeSlotPartCount(), (ui64)std::numeric_limits<std::uint16_t>::max() + 1);
-
- T *threadLoads[2];
- threadLoads[0] = new T;
- threadLoads[1] = new T;
-
- for (ui64 i = 1; i < timeSlotCount; i += 2) {
- threadLoads[0]->RegisterIdlePeriod(i * T::GetTimeSlotLengthNs());
- threadLoads[0]->RegisterBusyPeriod((i + 1) * T::GetTimeSlotLengthNs());
- }
-
- for (ui64 i = 1; i < timeSlotCount; i += 2) {
- threadLoads[1]->RegisterBusyPeriod(i * T::GetTimeSlotLengthNs());
- threadLoads[1]->RegisterIdlePeriod((i + 1) * T::GetTimeSlotLengthNs());
- }
-
- TMinusOneThreadEstimator estimator;
- ui64 value = estimator.MaxLatencyIncreaseWithOneLessCpu(threadLoads, 2, T::GetTimeWindowLengthNs(), T::GetTimeWindowLengthNs());
- UNIT_ASSERT_VALUES_EQUAL(value, 0);
-
- delete threadLoads[0];
- delete threadLoads[1];
- }
-
- Y_UNIT_TEST(MinusOneThreadEstimatorTwoThreadLoadsOneTimeSlotShift1) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
- constexpr auto threadCount = 2;
-
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, std::uint16_t>;
-
- T *threadLoads[threadCount];
-
- for (auto t = 0u; t < threadCount; ++t) {
- threadLoads[t] = new T;
-
- for (ui64 i = 2; i < threadLoads[t]->GetTimeSlotCount(); i += 2) {
- threadLoads[t]->RegisterIdlePeriod((i - 1) * T::GetTimeSlotLengthNs());
- threadLoads[t]->RegisterBusyPeriod(i * T::GetTimeSlotLengthNs());
- }
-
- threadLoads[t]->RegisterIdlePeriod((threadLoads[t]->GetTimeSlotCount() - 1) * T::GetTimeSlotLengthNs());
- threadLoads[t]->RegisterBusyPeriod(threadLoads[t]->GetTimeSlotCount() * T::GetTimeSlotLengthNs());
-
- for (ui64 s = 0; s < threadLoads[t]->GetTimeSlotCount(); ++s) {
- if (s % 2 == 1) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), T::GetTimeSlotMaxValue(), ToString(s).c_str());
- } else {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), 0, ToString(s).c_str());
- }
- }
- }
-
- TMinusOneThreadEstimator estimator;
- auto result = estimator.MaxLatencyIncreaseWithOneLessCpu(threadLoads, threadCount, T::GetTimeWindowLengthNs(), T::GetTimeWindowLengthNs());
-
- for (ui64 t = 0; t < threadCount; ++t) {
- for (ui64 s = 0; s < threadLoads[t]->GetTimeSlotCount(); ++s) {
- if (s % 2 == 1) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), T::GetTimeSlotMaxValue(), ToString(s).c_str());
- } else {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), 0, ToString(s).c_str());
- }
- }
- }
-
- UNIT_ASSERT_VALUES_EQUAL(result, T::GetTimeSlotLengthNs());
-
- for (auto t = 0u; t < threadCount; ++t) {
- delete threadLoads[t];
- }
- }
-
- Y_UNIT_TEST(MinusOneThreadEstimatorTwoThreadLoadsOneTimeSlotShift2) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
- constexpr auto threadCount = 2;
-
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, std::uint16_t>;
-
- T *threadLoads[threadCount];
-
- for (auto t = 0u; t < threadCount; ++t) {
- threadLoads[t] = new T;
-
- for (ui64 i = 2; i < threadLoads[t]->GetTimeSlotCount(); i += 2) {
- threadLoads[t]->RegisterBusyPeriod((i - 1) * T::GetTimeSlotLengthNs());
- threadLoads[t]->RegisterIdlePeriod(i * T::GetTimeSlotLengthNs());
- }
-
- threadLoads[t]->RegisterBusyPeriod((threadLoads[t]->GetTimeSlotCount() - 1) * T::GetTimeSlotLengthNs());
- threadLoads[t]->RegisterIdlePeriod(threadLoads[t]->GetTimeSlotCount() * T::GetTimeSlotLengthNs());
-
- for (ui64 s = 0; s < threadLoads[t]->GetTimeSlotCount(); ++s) {
- if (s % 2 == 0) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), T::GetTimeSlotMaxValue(), ToString(s).c_str());
- } else {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), 0, ToString(s).c_str());
- }
- }
- }
-
- TMinusOneThreadEstimator estimator;
- auto result = estimator.MaxLatencyIncreaseWithOneLessCpu(threadLoads, threadCount, T::GetTimeWindowLengthNs(), T::GetTimeWindowLengthNs());
-
- for (ui64 t = 0; t < threadCount; ++t) {
- for (ui64 s = 0; s < threadLoads[t]->GetTimeSlotCount(); ++s) {
- if (s % 2 == 0) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), T::GetTimeSlotMaxValue(), ToString(s).c_str());
- } else {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), 0, ToString(s).c_str());
- }
- }
- }
-
- UNIT_ASSERT_VALUES_EQUAL(result, T::GetTimeSlotLengthNs());
-
- for (auto t = 0u; t < threadCount; ++t) {
- delete threadLoads[t];
- }
- }
-
- Y_UNIT_TEST(MinusOneThreadEstimatorTwoThreadLoadsTwoTimeSlotsShift1) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
- constexpr auto threadCount = 2;
-
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, std::uint16_t>;
-
- T *threadLoads[threadCount];
-
- for (auto t = 0u; t < threadCount; ++t) {
- threadLoads[t] = new T;
-
- for (ui64 i = 4; i < threadLoads[t]->GetTimeSlotCount(); i += 4) {
- threadLoads[t]->RegisterIdlePeriod((i - 2) * T::GetTimeSlotLengthNs());
- threadLoads[t]->RegisterBusyPeriod(i * T::GetTimeSlotLengthNs());
- }
-
- threadLoads[t]->RegisterIdlePeriod((threadLoads[t]->GetTimeSlotCount() - 2) * T::GetTimeSlotLengthNs());
- threadLoads[t]->RegisterBusyPeriod(threadLoads[t]->GetTimeSlotCount() * T::GetTimeSlotLengthNs());
-
- for (ui64 s = 0; s < threadLoads[t]->GetTimeSlotCount(); ++s) {
- if (s % 4 == 2 || s % 4 == 3) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), T::GetTimeSlotMaxValue(), ToString(s).c_str());
- } else {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), 0, ToString(s).c_str());
- }
- }
- }
-
- TMinusOneThreadEstimator estimator;
- auto result = estimator.MaxLatencyIncreaseWithOneLessCpu(threadLoads, threadCount, T::GetTimeWindowLengthNs(), T::GetTimeWindowLengthNs());
-
- for (ui64 t = 0; t < threadCount; ++t) {
- for (ui64 s = 0; s < threadLoads[t]->GetTimeSlotCount(); ++s) {
- if (s % 4 == 2 || s % 4 == 3) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), T::GetTimeSlotMaxValue(), ToString(s).c_str());
- } else {
- UNIT_ASSERT_VALUES_EQUAL(threadLoads[t]->TimeSlots[s].load(), 0);
- }
- }
- }
-
- UNIT_ASSERT_VALUES_EQUAL(result, 2 * T::GetTimeSlotLengthNs());
-
- for (auto t = 0u; t < threadCount; ++t) {
- delete threadLoads[t];
- }
- }
-
- Y_UNIT_TEST(MinusOneThreadEstimatorTwoThreadLoadsTwoTimeSlotsShift2) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
- constexpr auto threadCount = 2;
-
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, std::uint16_t>;
-
- T *threadLoads[threadCount];
-
- for (auto t = 0u; t < threadCount; ++t) {
- threadLoads[t] = new T;
-
- for (ui64 i = 4; i < threadLoads[t]->GetTimeSlotCount(); i += 4) {
- threadLoads[t]->RegisterBusyPeriod((i - 2) * T::GetTimeSlotLengthNs());
- threadLoads[t]->RegisterIdlePeriod(i * T::GetTimeSlotLengthNs());
- }
-
- threadLoads[t]->RegisterBusyPeriod((threadLoads[t]->GetTimeSlotCount() - 2) * T::GetTimeSlotLengthNs());
- threadLoads[t]->RegisterIdlePeriod(threadLoads[t]->GetTimeSlotCount() * T::GetTimeSlotLengthNs());
-
- for (ui64 s = 0; s < threadLoads[t]->GetTimeSlotCount(); ++s) {
- if (s % 4 == 0 || s % 4 == 1) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), T::GetTimeSlotMaxValue(), ToString(s).c_str());
- } else {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), 0, ToString(s).c_str());
- }
- }
- }
-
- TMinusOneThreadEstimator estimator;
- auto result = estimator.MaxLatencyIncreaseWithOneLessCpu(threadLoads, threadCount, T::GetTimeWindowLengthNs(), T::GetTimeWindowLengthNs());
-
- for (ui64 t = 0; t < threadCount; ++t) {
- for (ui64 s = 0; s < threadLoads[t]->GetTimeSlotCount(); ++s) {
- if (s % 4 == 0 || s % 4 == 1) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), T::GetTimeSlotMaxValue(), ToString(s).c_str());
- } else {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), 0, ToString(s).c_str());
- }
- }
- }
-
- UNIT_ASSERT_VALUES_EQUAL(result, 2 * T::GetTimeSlotLengthNs());
-
- for (auto t = 0u; t < threadCount; ++t) {
- delete threadLoads[t];
- }
- }
-
- Y_UNIT_TEST(MinusOneThreadEstimatorTwoThreadLoadsTwoTimeSlotsShift3) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
- constexpr auto threadCount = 2;
-
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, std::uint16_t>;
-
- T *threadLoads[threadCount];
-
- for (auto t = 0u; t < threadCount; ++t) {
- threadLoads[t] = new T;
-
- auto timeNs = T::GetTimeWindowLengthNs() - 1.5 * T::GetTimeSlotLengthNs();
- threadLoads[t]->RegisterIdlePeriod(timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoads[t]->LastTimeNs.load(), timeNs);
-
- timeNs = T::GetTimeWindowLengthNs();
- threadLoads[t]->RegisterBusyPeriod(timeNs);
- UNIT_ASSERT_VALUES_EQUAL(threadLoads[t]->LastTimeNs.load(), timeNs);
-
- for (ui64 s = 0; s + 2 < threadLoads[t]->GetTimeSlotCount(); ++s) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), 0, ToString(s).c_str());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoads[t]->TimeSlots[timeSlotCount - 2].load(), T::GetTimeSlotPartCount() / 2);
- UNIT_ASSERT_VALUES_EQUAL(threadLoads[t]->TimeSlots[timeSlotCount - 1].load(), T::GetTimeSlotMaxValue());
- }
-
- TMinusOneThreadEstimator estimator;
- auto result = estimator.MaxLatencyIncreaseWithOneLessCpu(threadLoads, threadCount, T::GetTimeWindowLengthNs(), T::GetTimeWindowLengthNs());
-
- for (auto t = 0u; t < threadCount; ++t) {
- for (ui64 s = 0; s + 2 < threadLoads[t]->GetTimeSlotCount(); ++s) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), 0, ToString(s).c_str());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoads[t]->TimeSlots[timeSlotCount - 2].load(), T::GetTimeSlotPartCount() / 2);
- UNIT_ASSERT_VALUES_EQUAL(threadLoads[t]->TimeSlots[timeSlotCount - 1].load(), T::GetTimeSlotMaxValue());
- }
-
- UNIT_ASSERT_VALUES_EQUAL(result, 2 * T::GetTimeSlotLengthNs());
-
- for (auto t = 0u; t < threadCount; ++t) {
- delete threadLoads[t];
- }
- }
-
- Y_UNIT_TEST(MinusOneThreadEstimator16ThreadLoadsAllTimeSlots) {
- constexpr auto timeWindowLengthNs = 5368709120ull; // 5 * 2 ^ 30 ~5 sec
- constexpr auto timeSlotLengthNs = 524288ull; // 2 ^ 19 ns ~ 512 usec
- constexpr auto timeSlotCount = timeWindowLengthNs / timeSlotLengthNs;
- constexpr auto threadCount = 16;
- constexpr auto estimatesCount = 16;
-
- using T = TThreadLoad<timeSlotCount, timeSlotLengthNs, std::uint16_t>;
-
- for (auto e = 0u; e < estimatesCount; ++e) {
- T *threadLoads[threadCount];
-
- for (auto t = 0u; t < threadCount; ++t) {
- threadLoads[t] = new T;
- auto timeNs = threadLoads[t]->GetTimeWindowLengthNs();
- threadLoads[t]->RegisterBusyPeriod(timeNs);
-
- UNIT_ASSERT_VALUES_EQUAL(threadLoads[t]->LastTimeNs.load(), timeNs);
- for (ui64 s = 0; s < threadLoads[t]->GetTimeSlotCount(); ++s) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), T::GetTimeSlotMaxValue(), ToString(s).c_str());
- }
- }
-
- ui64 result = 0;
- {
- THPTimer timer;
- TMinusOneThreadEstimator estimator;
- result = estimator.MaxLatencyIncreaseWithOneLessCpu(threadLoads, threadCount, T::GetTimeWindowLengthNs(), T::GetTimeWindowLengthNs());
- // output in microseconds
- auto passed = timer.Passed() * 1000000;
- Y_UNUSED(passed);
- // Cerr << "timer : " << passed << " " << __LINE__ << Endl;
- }
-
- for (ui64 t = 0; t < threadCount; ++t) {
- UNIT_ASSERT_VALUES_EQUAL(threadLoads[t]->LastTimeNs.load(), T::GetTimeWindowLengthNs());
- for (ui64 s = 0; s < threadLoads[t]->GetTimeSlotCount(); ++s) {
- UNIT_ASSERT_VALUES_EQUAL_C(threadLoads[t]->TimeSlots[s].load(), T::GetTimeSlotMaxValue(), ToString(s).c_str());
- }
- }
-
- UNIT_ASSERT_VALUES_EQUAL(result, T::GetTimeWindowLengthNs());
-
- for (auto t = 0u; t < threadCount; ++t) {
- delete threadLoads[t];
- }
- }
- }
-}
diff --git a/library/cpp/actors/util/threadparkpad.cpp b/library/cpp/actors/util/threadparkpad.cpp
deleted file mode 100644
index b939d6b61a..0000000000
--- a/library/cpp/actors/util/threadparkpad.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-#include "threadparkpad.h"
-#include <util/system/winint.h>
-
-#ifdef _linux_
-
-#include "futex.h"
-
-namespace NActors {
- class TThreadParkPad::TImpl {
- volatile bool Interrupted;
- int Futex;
-
- public:
- TImpl()
- : Interrupted(false)
- , Futex(0)
- {
- }
- ~TImpl() {
- }
-
- bool Park() noexcept {
- __atomic_fetch_sub(&Futex, 1, __ATOMIC_SEQ_CST);
- while (__atomic_load_n(&Futex, __ATOMIC_ACQUIRE) == -1)
- SysFutex(&Futex, FUTEX_WAIT_PRIVATE, -1, nullptr, nullptr, 0);
- return IsInterrupted();
- }
-
- void Unpark() noexcept {
- const int old = __atomic_fetch_add(&Futex, 1, __ATOMIC_SEQ_CST);
- if (old == -1)
- SysFutex(&Futex, FUTEX_WAKE_PRIVATE, -1, nullptr, nullptr, 0);
- }
-
- void Interrupt() noexcept {
- __atomic_store_n(&Interrupted, true, __ATOMIC_SEQ_CST);
- Unpark();
- }
-
- bool IsInterrupted() const noexcept {
- return __atomic_load_n(&Interrupted, __ATOMIC_ACQUIRE);
- }
- };
-
-#elif defined _win32_
-#include <library/cpp/deprecated/atomic/atomic.h>
-
-#include <util/generic/bt_exception.h>
-#include <util/generic/yexception.h>
-
-namespace NActors {
- class TThreadParkPad::TImpl {
- TAtomic Interrupted;
- HANDLE EvHandle;
-
- public:
- TImpl()
- : Interrupted(false)
- {
- EvHandle = ::CreateEvent(0, false, false, 0);
- if (!EvHandle)
- ythrow TWithBackTrace<yexception>() << "::CreateEvent failed";
- }
- ~TImpl() {
- if (EvHandle)
- ::CloseHandle(EvHandle);
- }
-
- bool Park() noexcept {
- ::WaitForSingleObject(EvHandle, INFINITE);
- return AtomicGet(Interrupted);
- }
-
- void Unpark() noexcept {
- ::SetEvent(EvHandle);
- }
-
- void Interrupt() noexcept {
- AtomicSet(Interrupted, true);
- Unpark();
- }
-
- bool IsInterrupted() const noexcept {
- return AtomicGet(Interrupted);
- }
- };
-
-#else
-
-#include <library/cpp/deprecated/atomic/atomic.h>
-
-#include <util/system/event.h>
-
-namespace NActors {
- class TThreadParkPad::TImpl {
- TAtomic Interrupted;
- TSystemEvent Ev;
-
- public:
- TImpl()
- : Interrupted(false)
- , Ev(TSystemEvent::rAuto)
- {
- }
- ~TImpl() {
- }
-
- bool Park() noexcept {
- Ev.Wait();
- return AtomicGet(Interrupted);
- }
-
- void Unpark() noexcept {
- Ev.Signal();
- }
-
- void Interrupt() noexcept {
- AtomicSet(Interrupted, true);
- Unpark();
- }
-
- bool IsInterrupted() const noexcept {
- return AtomicGet(Interrupted);
- }
- };
-#endif
-
- TThreadParkPad::TThreadParkPad()
- : Impl(new TThreadParkPad::TImpl())
- {
- }
-
- TThreadParkPad::~TThreadParkPad() {
- }
-
- bool TThreadParkPad::Park() noexcept {
- return Impl->Park();
- }
-
- void TThreadParkPad::Unpark() noexcept {
- Impl->Unpark();
- }
-
- void TThreadParkPad::Interrupt() noexcept {
- Impl->Interrupt();
- }
-
- bool TThreadParkPad::Interrupted() const noexcept {
- return Impl->IsInterrupted();
- }
-
-}
diff --git a/library/cpp/actors/util/threadparkpad.h b/library/cpp/actors/util/threadparkpad.h
deleted file mode 100644
index 5b574ccf34..0000000000
--- a/library/cpp/actors/util/threadparkpad.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include <util/generic/ptr.h>
-
-namespace NActors {
- class TThreadParkPad {
- private:
- class TImpl;
- THolder<TImpl> Impl;
-
- public:
- TThreadParkPad();
- ~TThreadParkPad();
-
- bool Park() noexcept;
- void Unpark() noexcept;
- void Interrupt() noexcept;
- bool Interrupted() const noexcept;
- };
-
-}
diff --git a/library/cpp/actors/util/ticket_lock.h b/library/cpp/actors/util/ticket_lock.h
deleted file mode 100644
index 30355c3390..0000000000
--- a/library/cpp/actors/util/ticket_lock.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-
-#include "intrinsics.h"
-#include <util/system/guard.h>
-#include <util/system/yassert.h>
-
-class TTicketLock : TNonCopyable {
- ui32 TicketIn;
- ui32 TicketOut;
-
-public:
- TTicketLock()
- : TicketIn(0)
- , TicketOut(0)
- {
- }
-
- void Release() noexcept {
- AtomicUi32Increment(&TicketOut);
- }
-
- ui32 Acquire() noexcept {
- ui32 revolves = 0;
- const ui32 ticket = AtomicUi32Increment(&TicketIn) - 1;
- while (ticket != AtomicLoad(&TicketOut)) {
- Y_DEBUG_ABORT_UNLESS(ticket >= AtomicLoad(&TicketOut));
- SpinLockPause();
- ++revolves;
- }
- return revolves;
- }
-
- bool TryAcquire() noexcept {
- const ui32 x = AtomicLoad(&TicketOut);
- if (x == AtomicLoad(&TicketIn) && AtomicUi32Cas(&TicketIn, x + 1, x))
- return true;
- else
- return false;
- }
-
- bool IsLocked() noexcept {
- const ui32 ticketIn = AtomicLoad(&TicketIn);
- const ui32 ticketOut = AtomicLoad(&TicketOut);
- return (ticketIn != ticketOut);
- }
-
- typedef ::TGuard<TTicketLock> TGuard;
-};
diff --git a/library/cpp/actors/util/timerfd.h b/library/cpp/actors/util/timerfd.h
deleted file mode 100644
index 78ae27e2ee..0000000000
--- a/library/cpp/actors/util/timerfd.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#pragma once
-
-#include "datetime.h"
-
-#include <util/generic/noncopyable.h>
-
-#ifdef _linux_
-
-#include <util/system/yassert.h>
-#include <errno.h>
-#include <sys/timerfd.h>
-
-struct TTimerFd: public TNonCopyable {
- int Fd;
-
- TTimerFd() {
- Fd = timerfd_create(CLOCK_MONOTONIC, 0);
- Y_ABORT_UNLESS(Fd != -1, "timerfd_create(CLOCK_MONOTONIC, 0) -> -1; errno:%d: %s", int(errno), strerror(errno));
- }
-
- ~TTimerFd() {
- close(Fd);
- }
-
- void Set(ui64 ts) {
- ui64 now = GetCycleCountFast();
- Arm(now >= ts? 1: NHPTimer::GetSeconds(ts - now) * 1e9);
- }
-
- void Reset() {
- Arm(0); // disarm timer
- }
-
- void Wait() {
- ui64 expirations;
- ssize_t s = read(Fd, &expirations, sizeof(ui64));
- Y_UNUSED(s); // Y_ABORT_UNLESS(s == sizeof(ui64));
- }
-
- void Wake() {
- Arm(1);
- }
-private:
- void Arm(ui64 ns) {
- struct itimerspec spec;
- spec.it_value.tv_sec = ns / 1'000'000'000;
- spec.it_value.tv_nsec = ns % 1'000'000'000;
- spec.it_interval.tv_sec = 0;
- spec.it_interval.tv_nsec = 0;
- int ret = timerfd_settime(Fd, 0, &spec, nullptr);
- Y_ABORT_UNLESS(ret != -1, "timerfd_settime(%d, 0, %" PRIu64 "ns, 0) -> %d; errno:%d: %s", Fd, ns, ret, int(errno), strerror(errno));
- }
-};
-
-#else
-
-struct TTimerFd: public TNonCopyable {
- int Fd = 0;
- void Set(ui64) {}
- void Reset() {}
- void Wait() {}
- void Wake() {}
-};
-
-#endif
diff --git a/library/cpp/actors/util/unordered_cache.h b/library/cpp/actors/util/unordered_cache.h
deleted file mode 100644
index 40794fc04b..0000000000
--- a/library/cpp/actors/util/unordered_cache.h
+++ /dev/null
@@ -1,201 +0,0 @@
-#pragma once
-
-#include "defs.h"
-#include "queue_chunk.h"
-
-template <typename T, ui32 Size = 512, ui32 ConcurrencyFactor = 1, typename TChunk = TQueueChunk<T, Size>>
-class TUnorderedCache : TNonCopyable {
- static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value");
-
-public:
- static constexpr ui32 Concurrency = ConcurrencyFactor * 4;
-
-private:
- struct TReadSlot {
- TChunk* volatile ReadFrom;
- volatile ui32 ReadPosition;
- char Padding[64 - sizeof(TChunk*) - sizeof(ui32)]; // 1 slot per cache line
- };
-
- struct TWriteSlot {
- TChunk* volatile WriteTo;
- volatile ui32 WritePosition;
- char Padding[64 - sizeof(TChunk*) - sizeof(ui32)]; // 1 slot per cache line
- };
-
- static_assert(sizeof(TReadSlot) == 64, "expect sizeof(TReadSlot) == 64");
- static_assert(sizeof(TWriteSlot) == 64, "expect sizeof(TWriteSlot) == 64");
-
-private:
- TReadSlot ReadSlots[Concurrency];
- TWriteSlot WriteSlots[Concurrency];
-
- static_assert(sizeof(TChunk*) == sizeof(TAtomic), "expect sizeof(TChunk*) == sizeof(TAtomic)");
-
-private:
- struct TLockedWriter {
- TWriteSlot* Slot;
- TChunk* WriteTo;
-
- TLockedWriter()
- : Slot(nullptr)
- , WriteTo(nullptr)
- { }
-
- TLockedWriter(TWriteSlot* slot, TChunk* writeTo)
- : Slot(slot)
- , WriteTo(writeTo)
- { }
-
- ~TLockedWriter() noexcept {
- Drop();
- }
-
- void Drop() {
- if (Slot) {
- AtomicStore(&Slot->WriteTo, WriteTo);
- Slot = nullptr;
- }
- }
-
- TLockedWriter(const TLockedWriter&) = delete;
- TLockedWriter& operator=(const TLockedWriter&) = delete;
-
- TLockedWriter(TLockedWriter&& rhs)
- : Slot(rhs.Slot)
- , WriteTo(rhs.WriteTo)
- {
- rhs.Slot = nullptr;
- }
-
- TLockedWriter& operator=(TLockedWriter&& rhs) {
- if (Y_LIKELY(this != &rhs)) {
- Drop();
- Slot = rhs.Slot;
- WriteTo = rhs.WriteTo;
- rhs.Slot = nullptr;
- }
- return *this;
- }
- };
-
-private:
- TLockedWriter LockWriter(ui64 writerRotation) {
- ui32 cycle = 0;
- for (;;) {
- TWriteSlot* slot = &WriteSlots[writerRotation % Concurrency];
- if (AtomicLoad(&slot->WriteTo) != nullptr) {
- if (TChunk* writeTo = AtomicSwap(&slot->WriteTo, nullptr)) {
- return TLockedWriter(slot, writeTo);
- }
- }
- ++writerRotation;
-
- // Do a spinlock pause after a full cycle
- if (++cycle == Concurrency) {
- SpinLockPause();
- cycle = 0;
- }
- }
- }
-
- void WriteOne(TLockedWriter& lock, T x) {
- Y_DEBUG_ABORT_UNLESS(x != 0);
-
- const ui32 pos = AtomicLoad(&lock.Slot->WritePosition);
- if (pos != TChunk::EntriesCount) {
- AtomicStore(&lock.Slot->WritePosition, pos + 1);
- AtomicStore(&lock.WriteTo->Entries[pos], x);
- } else {
- TChunk* next = new TChunk();
- AtomicStore(&next->Entries[0], x);
- AtomicStore(&lock.Slot->WritePosition, 1u);
- AtomicStore(&lock.WriteTo->Next, next);
- lock.WriteTo = next;
- }
- }
-
-public:
- TUnorderedCache() {
- for (ui32 i = 0; i < Concurrency; ++i) {
- ReadSlots[i].ReadFrom = new TChunk();
- ReadSlots[i].ReadPosition = 0;
-
- WriteSlots[i].WriteTo = ReadSlots[i].ReadFrom;
- WriteSlots[i].WritePosition = 0;
- }
- }
-
- ~TUnorderedCache() {
- Y_ABORT_UNLESS(!Pop(0));
-
- for (ui64 i = 0; i < Concurrency; ++i) {
- if (ReadSlots[i].ReadFrom) {
- delete ReadSlots[i].ReadFrom;
- ReadSlots[i].ReadFrom = nullptr;
- }
- WriteSlots[i].WriteTo = nullptr;
- }
- }
-
- T Pop(ui64 readerRotation) noexcept {
- ui64 readerIndex = readerRotation;
- const ui64 endIndex = readerIndex + Concurrency;
- for (; readerIndex != endIndex; ++readerIndex) {
- TReadSlot* slot = &ReadSlots[readerIndex % Concurrency];
- if (AtomicLoad(&slot->ReadFrom) != nullptr) {
- if (TChunk* readFrom = AtomicSwap(&slot->ReadFrom, nullptr)) {
- const ui32 pos = AtomicLoad(&slot->ReadPosition);
- if (pos != TChunk::EntriesCount) {
- if (T ret = AtomicLoad(&readFrom->Entries[pos])) {
- AtomicStore(&slot->ReadPosition, pos + 1);
- AtomicStore(&slot->ReadFrom, readFrom); // release lock with same chunk
- return ret; // found, return
- } else {
- AtomicStore(&slot->ReadFrom, readFrom); // release lock with same chunk
- }
- } else if (TChunk* next = AtomicLoad(&readFrom->Next)) {
- if (T ret = AtomicLoad(&next->Entries[0])) {
- AtomicStore(&slot->ReadPosition, 1u);
- AtomicStore(&slot->ReadFrom, next); // release lock with next chunk
- delete readFrom;
- return ret;
- } else {
- AtomicStore(&slot->ReadPosition, 0u);
- AtomicStore(&slot->ReadFrom, next); // release lock with new chunk
- delete readFrom;
- }
- } else {
- // nothing in old chunk and no next chunk, just release lock with old chunk
- AtomicStore(&slot->ReadFrom, readFrom);
- }
- }
- }
- }
-
- return 0; // got nothing after full cycle, return
- }
-
- void Push(T x, ui64 writerRotation) {
- TLockedWriter lock = LockWriter(writerRotation);
- WriteOne(lock, x);
- }
-
- void PushBulk(T* x, ui32 xcount, ui64 writerRotation) {
- for (;;) {
- // Fill no more then one queue chunk per round
- const ui32 xround = Min(xcount, (ui32)TChunk::EntriesCount);
-
- {
- TLockedWriter lock = LockWriter(writerRotation++);
- for (T* end = x + xround; x != end; ++x)
- WriteOne(lock, *x);
- }
-
- if (xcount <= TChunk::EntriesCount)
- break;
-
- xcount -= TChunk::EntriesCount;
- }
- }
-};
diff --git a/library/cpp/actors/util/unordered_cache_ut.cpp b/library/cpp/actors/util/unordered_cache_ut.cpp
deleted file mode 100644
index 37865f2f91..0000000000
--- a/library/cpp/actors/util/unordered_cache_ut.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-#include "unordered_cache.h"
-
-#include <library/cpp/testing/unittest/registar.h>
-#include <util/random/random.h>
-#include <util/system/hp_timer.h>
-#include <util/system/sanitizers.h>
-#include <util/system/thread.h>
-
-Y_UNIT_TEST_SUITE(UnorderedCache) {
-
- void DoOnePushOnePop(ui64 count) {
- TUnorderedCache<ui64> queue;
-
- ui64 readRotation = 0;
- ui64 writeRotation = 0;
-
- auto popped = queue.Pop(readRotation++);
- UNIT_ASSERT_VALUES_EQUAL(popped, 0u);
-
- for (ui64 i = 0; i < count; ++i) {
- queue.Push(i + 1, writeRotation++);
- popped = queue.Pop(readRotation++);
- UNIT_ASSERT_VALUES_EQUAL(popped, i + 1);
-
- popped = queue.Pop(readRotation++);
- UNIT_ASSERT_VALUES_EQUAL(popped, 0u);
- }
- }
-
- Y_UNIT_TEST(OnePushOnePop) {
- DoOnePushOnePop(1);
- }
-
- Y_UNIT_TEST(OnePushOnePop_Repeat1M) {
- DoOnePushOnePop(1000000);
- }
-
- /**
- * Simplified thread spawning for testing
- */
- class TWorkerThread : public ISimpleThread {
- private:
- std::function<void()> Func;
- double Time = 0.0;
-
- public:
- TWorkerThread(std::function<void()> func)
- : Func(std::move(func))
- { }
-
- double GetTime() const {
- return Time;
- }
-
- static THolder<TWorkerThread> Spawn(std::function<void()> func) {
- THolder<TWorkerThread> thread = MakeHolder<TWorkerThread>(std::move(func));
- thread->Start();
- return thread;
- }
-
- private:
- void* ThreadProc() noexcept override {
- THPTimer timer;
- Func();
- Time = timer.Passed();
- return nullptr;
- }
- };
-
- void DoConcurrentPushPop(size_t threads, ui64 perThreadCount) {
- // Concurrency factor 4 is up to 16 threads
- TUnorderedCache<ui64, 512, 4> queue;
-
- auto workerFunc = [&](size_t threadIndex) {
- ui64 readRotation = 0;
- ui64 writeRotation = 0;
- ui64 readsDone = 0;
- ui64 writesDone = 0;
- for (;;) {
- bool canRead = readsDone < writesDone;
- bool canWrite = writesDone < perThreadCount;
- if (!canRead && !canWrite) {
- break;
- }
- if (canRead && canWrite) {
- // Randomly choose between read and write
- if (RandomNumber<ui64>(2)) {
- canRead = false;
- } else {
- canWrite = false;
- }
- }
- if (canRead) {
- ui64 popped = queue.Pop(readRotation++);
- if (popped) {
- ++readsDone;
- }
- }
- if (canWrite) {
- queue.Push(1 + writesDone * threads + threadIndex, writeRotation++);
- ++writesDone;
- }
- }
- };
-
- TVector<THolder<TWorkerThread>> workers(threads);
- for (size_t i = 0; i < threads; ++i) {
- workers[i] = TWorkerThread::Spawn([workerFunc, i]() {
- workerFunc(i);
- });
- }
-
- double maxTime = 0;
- for (size_t i = 0; i < threads; ++i) {
- workers[i]->Join();
- maxTime = Max(maxTime, workers[i]->GetTime());
- }
-
- auto popped = queue.Pop(0);
- UNIT_ASSERT_VALUES_EQUAL(popped, 0u);
-
- Cerr << "Concurrent with " << threads << " threads: " << maxTime << " seconds" << Endl;
- }
-
- void DoConcurrentPushPop_3times(size_t threads, ui64 perThreadCount) {
- for (size_t i = 0; i < 3; ++i) {
- DoConcurrentPushPop(threads, perThreadCount);
- }
- }
-
- static constexpr ui64 PER_THREAD_COUNT = NSan::PlainOrUnderSanitizer(1000000, 100000);
-
- Y_UNIT_TEST(ConcurrentPushPop_1thread) { DoConcurrentPushPop_3times(1, PER_THREAD_COUNT); }
- Y_UNIT_TEST(ConcurrentPushPop_2threads) { DoConcurrentPushPop_3times(2, PER_THREAD_COUNT); }
- Y_UNIT_TEST(ConcurrentPushPop_4threads) { DoConcurrentPushPop_3times(4, PER_THREAD_COUNT); }
- Y_UNIT_TEST(ConcurrentPushPop_8threads) { DoConcurrentPushPop_3times(8, PER_THREAD_COUNT); }
- Y_UNIT_TEST(ConcurrentPushPop_16threads) { DoConcurrentPushPop_3times(16, PER_THREAD_COUNT); }
-}
diff --git a/library/cpp/actors/util/ut/CMakeLists.darwin-arm64.txt b/library/cpp/actors/util/ut/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 9b02cd1836..0000000000
--- a/library/cpp/actors/util/ut/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-util-ut)
-target_include_directories(library-cpp-actors-util-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util
-)
-target_link_libraries(library-cpp-actors-util-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-util
-)
-target_link_options(library-cpp-actors-util-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-util-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/cpu_load_log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_tracker_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/thread_load_log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rope_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rc_buf_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_rope_backend_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_native_rope_backend_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/unordered_cache_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-util-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-util-ut
- TEST_TARGET
- library-cpp-actors-util-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-util-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-util-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-util-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-util-ut)
diff --git a/library/cpp/actors/util/ut/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/util/ut/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index f02b2d926c..0000000000
--- a/library/cpp/actors/util/ut/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-util-ut)
-target_include_directories(library-cpp-actors-util-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util
-)
-target_link_libraries(library-cpp-actors-util-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-util
-)
-target_link_options(library-cpp-actors-util-ut PRIVATE
- -Wl,-platform_version,macos,11.0,11.0
- -fPIC
- -fPIC
- -framework
- CoreFoundation
-)
-target_sources(library-cpp-actors-util-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/cpu_load_log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_tracker_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/thread_load_log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rope_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rc_buf_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_rope_backend_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_native_rope_backend_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/unordered_cache_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-util-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-util-ut
- TEST_TARGET
- library-cpp-actors-util-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-util-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-util-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-util-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-util-ut)
diff --git a/library/cpp/actors/util/ut/CMakeLists.linux-aarch64.txt b/library/cpp/actors/util/ut/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 27ff864fef..0000000000
--- a/library/cpp/actors/util/ut/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-util-ut)
-target_include_directories(library-cpp-actors-util-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util
-)
-target_link_libraries(library-cpp-actors-util-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-testing-unittest_main
- cpp-actors-util
-)
-target_link_options(library-cpp-actors-util-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-util-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/cpu_load_log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_tracker_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/thread_load_log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rope_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rc_buf_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_rope_backend_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_native_rope_backend_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/unordered_cache_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-util-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-util-ut
- TEST_TARGET
- library-cpp-actors-util-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-util-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-util-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-util-ut
- cpp-malloc-jemalloc
-)
-vcs_info(library-cpp-actors-util-ut)
diff --git a/library/cpp/actors/util/ut/CMakeLists.linux-x86_64.txt b/library/cpp/actors/util/ut/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index d1143a475b..0000000000
--- a/library/cpp/actors/util/ut/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-util-ut)
-target_include_directories(library-cpp-actors-util-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util
-)
-target_link_libraries(library-cpp-actors-util-ut PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-util
-)
-target_link_options(library-cpp-actors-util-ut PRIVATE
- -ldl
- -lrt
- -Wl,--no-as-needed
- -fPIC
- -fPIC
- -lpthread
- -lrt
- -ldl
-)
-target_sources(library-cpp-actors-util-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/cpu_load_log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_tracker_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/thread_load_log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rope_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rc_buf_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_rope_backend_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_native_rope_backend_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/unordered_cache_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-util-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-util-ut
- TEST_TARGET
- library-cpp-actors-util-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-util-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-util-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-util-ut
- cpp-malloc-tcmalloc
- libs-tcmalloc-no_percpu_cache
-)
-vcs_info(library-cpp-actors-util-ut)
diff --git a/library/cpp/actors/util/ut/CMakeLists.txt b/library/cpp/actors/util/ut/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/util/ut/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/util/ut/CMakeLists.windows-x86_64.txt b/library/cpp/actors/util/ut/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 3af5d98ef0..0000000000
--- a/library/cpp/actors/util/ut/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_executable(library-cpp-actors-util-ut)
-target_include_directories(library-cpp-actors-util-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util
-)
-target_link_libraries(library-cpp-actors-util-ut PUBLIC
- contrib-libs-cxxsupp
- yutil
- library-cpp-cpuid_check
- cpp-testing-unittest_main
- cpp-actors-util
-)
-target_sources(library-cpp-actors-util-ut PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/cpu_load_log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/memory_tracker_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/thread_load_log_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rope_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/rc_buf_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_rope_backend_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/shared_data_native_rope_backend_ut.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/util/unordered_cache_ut.cpp
-)
-set_property(
- TARGET
- library-cpp-actors-util-ut
- PROPERTY
- SPLIT_FACTOR
- 1
-)
-add_yunittest(
- NAME
- library-cpp-actors-util-ut
- TEST_TARGET
- library-cpp-actors-util-ut
- TEST_ARG
- --print-before-suite
- --print-before-test
- --fork-tests
- --print-times
- --show-fails
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-util-ut
- PROPERTY
- LABELS
- SMALL
-)
-set_yunittest_property(
- TEST
- library-cpp-actors-util-ut
- PROPERTY
- PROCESSORS
- 1
-)
-target_allocator(library-cpp-actors-util-ut
- system_allocator
-)
-vcs_info(library-cpp-actors-util-ut)
diff --git a/library/cpp/actors/util/ut/ya.make b/library/cpp/actors/util/ut/ya.make
deleted file mode 100644
index 9ac8504751..0000000000
--- a/library/cpp/actors/util/ut/ya.make
+++ /dev/null
@@ -1,20 +0,0 @@
-UNITTEST_FOR(library/cpp/actors/util)
-
-IF (WITH_VALGRIND)
- TIMEOUT(600)
- SIZE(MEDIUM)
-ENDIF()
-
-SRCS(
- cpu_load_log_ut.cpp
- memory_tracker_ut.cpp
- thread_load_log_ut.cpp
- rope_ut.cpp
- rc_buf_ut.cpp
- shared_data_ut.cpp
- shared_data_rope_backend_ut.cpp
- shared_data_native_rope_backend_ut.cpp
- unordered_cache_ut.cpp
-)
-
-END()
diff --git a/library/cpp/actors/util/ut_helpers.h b/library/cpp/actors/util/ut_helpers.h
deleted file mode 100644
index d3fe873233..0000000000
--- a/library/cpp/actors/util/ut_helpers.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-// calls TCallback for all args permutations including (id, id)
-template <class TCallback, class... TArgs>
-void Permutate(TCallback&& fn, TArgs&&... args)
-{
- auto forAll = [&](auto& arg){
- (fn(std::forward<decltype(arg)>(arg), std::forward<decltype(args)>(args)), ...);
- };
-
- (forAll(std::forward<decltype(args)>(args)), ...);
-}
diff --git a/library/cpp/actors/util/ya.make b/library/cpp/actors/util/ya.make
deleted file mode 100644
index 48d595c156..0000000000
--- a/library/cpp/actors/util/ya.make
+++ /dev/null
@@ -1,50 +0,0 @@
-LIBRARY()
-
-SRCS(
- affinity.cpp
- affinity.h
- cpu_load_log.h
- cpumask.h
- datetime.h
- defs.h
- funnel_queue.h
- futex.h
- intrinsics.h
- local_process_key.h
- named_tuple.h
- queue_chunk.h
- queue_oneone_inplace.h
- memory_track.cpp
- memory_track.h
- memory_tracker.cpp
- memory_tracker.h
- recentwnd.h
- rope.cpp
- rope.h
- rc_buf.cpp
- rc_buf.h
- shared_data.h
- shared_data.cpp
- shared_data_rope_backend.h
- should_continue.cpp
- should_continue.h
- thread.h
- threadparkpad.cpp
- threadparkpad.h
- thread_load_log.h
- ticket_lock.h
- timerfd.h
- unordered_cache.h
-)
-
-PEERDIR(
- library/cpp/containers/absl_flat_hash
- library/cpp/deprecated/atomic
- library/cpp/pop_count
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- ut
-)
diff --git a/library/cpp/actors/wilson/CMakeLists.darwin-arm64.txt b/library/cpp/actors/wilson/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 45704ccd5a..0000000000
--- a/library/cpp/actors/wilson/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(protos)
-
-add_library(cpp-actors-wilson)
-target_link_libraries(cpp-actors-wilson PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-actors-protos
- actors-wilson-protos
-)
-target_sources(cpp-actors-wilson PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_event.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_span.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_profile_span.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_trace.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_uploader.cpp
-)
diff --git a/library/cpp/actors/wilson/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/wilson/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 45704ccd5a..0000000000
--- a/library/cpp/actors/wilson/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(protos)
-
-add_library(cpp-actors-wilson)
-target_link_libraries(cpp-actors-wilson PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-actors-protos
- actors-wilson-protos
-)
-target_sources(cpp-actors-wilson PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_event.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_span.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_profile_span.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_trace.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_uploader.cpp
-)
diff --git a/library/cpp/actors/wilson/CMakeLists.linux-aarch64.txt b/library/cpp/actors/wilson/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index ccc87489ae..0000000000
--- a/library/cpp/actors/wilson/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(protos)
-
-add_library(cpp-actors-wilson)
-target_link_libraries(cpp-actors-wilson PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-actors-protos
- actors-wilson-protos
-)
-target_sources(cpp-actors-wilson PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_event.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_span.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_profile_span.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_trace.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_uploader.cpp
-)
diff --git a/library/cpp/actors/wilson/CMakeLists.linux-x86_64.txt b/library/cpp/actors/wilson/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index ccc87489ae..0000000000
--- a/library/cpp/actors/wilson/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(protos)
-
-add_library(cpp-actors-wilson)
-target_link_libraries(cpp-actors-wilson PUBLIC
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-actors-protos
- actors-wilson-protos
-)
-target_sources(cpp-actors-wilson PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_event.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_span.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_profile_span.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_trace.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_uploader.cpp
-)
diff --git a/library/cpp/actors/wilson/CMakeLists.txt b/library/cpp/actors/wilson/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/wilson/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/wilson/CMakeLists.windows-x86_64.txt b/library/cpp/actors/wilson/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 45704ccd5a..0000000000
--- a/library/cpp/actors/wilson/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-add_subdirectory(protos)
-
-add_library(cpp-actors-wilson)
-target_link_libraries(cpp-actors-wilson PUBLIC
- contrib-libs-cxxsupp
- yutil
- cpp-actors-core
- cpp-actors-protos
- actors-wilson-protos
-)
-target_sources(cpp-actors-wilson PRIVATE
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_event.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_span.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_profile_span.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_trace.cpp
- ${CMAKE_SOURCE_DIR}/library/cpp/actors/wilson/wilson_uploader.cpp
-)
diff --git a/library/cpp/actors/wilson/protos/CMakeLists.darwin-arm64.txt b/library/cpp/actors/wilson/protos/CMakeLists.darwin-arm64.txt
deleted file mode 100644
index 92afc01bb4..0000000000
--- a/library/cpp/actors/wilson/protos/CMakeLists.darwin-arm64.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(actors-wilson-protos INTERFACE)
-target_link_libraries(actors-wilson-protos INTERFACE
- contrib-libs-cxxsupp
- yutil
- contrib-libs-opentelemetry-proto
-)
diff --git a/library/cpp/actors/wilson/protos/CMakeLists.darwin-x86_64.txt b/library/cpp/actors/wilson/protos/CMakeLists.darwin-x86_64.txt
deleted file mode 100644
index 92afc01bb4..0000000000
--- a/library/cpp/actors/wilson/protos/CMakeLists.darwin-x86_64.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(actors-wilson-protos INTERFACE)
-target_link_libraries(actors-wilson-protos INTERFACE
- contrib-libs-cxxsupp
- yutil
- contrib-libs-opentelemetry-proto
-)
diff --git a/library/cpp/actors/wilson/protos/CMakeLists.linux-aarch64.txt b/library/cpp/actors/wilson/protos/CMakeLists.linux-aarch64.txt
deleted file mode 100644
index 101316f4fc..0000000000
--- a/library/cpp/actors/wilson/protos/CMakeLists.linux-aarch64.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(actors-wilson-protos INTERFACE)
-target_link_libraries(actors-wilson-protos INTERFACE
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-opentelemetry-proto
-)
diff --git a/library/cpp/actors/wilson/protos/CMakeLists.linux-x86_64.txt b/library/cpp/actors/wilson/protos/CMakeLists.linux-x86_64.txt
deleted file mode 100644
index 101316f4fc..0000000000
--- a/library/cpp/actors/wilson/protos/CMakeLists.linux-x86_64.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(actors-wilson-protos INTERFACE)
-target_link_libraries(actors-wilson-protos INTERFACE
- contrib-libs-linux-headers
- contrib-libs-cxxsupp
- yutil
- contrib-libs-opentelemetry-proto
-)
diff --git a/library/cpp/actors/wilson/protos/CMakeLists.txt b/library/cpp/actors/wilson/protos/CMakeLists.txt
deleted file mode 100644
index 2dce3a77fe..0000000000
--- a/library/cpp/actors/wilson/protos/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-aarch64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
- include(CMakeLists.darwin-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- include(CMakeLists.darwin-arm64.txt)
-elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
- include(CMakeLists.windows-x86_64.txt)
-elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
- include(CMakeLists.linux-x86_64.txt)
-endif()
diff --git a/library/cpp/actors/wilson/protos/CMakeLists.windows-x86_64.txt b/library/cpp/actors/wilson/protos/CMakeLists.windows-x86_64.txt
deleted file mode 100644
index 92afc01bb4..0000000000
--- a/library/cpp/actors/wilson/protos/CMakeLists.windows-x86_64.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# This file was generated by the build system used internally in the Yandex monorepo.
-# Only simple modifications are allowed (adding source-files to targets, adding simple properties
-# like target_include_directories). These modifications will be ported to original
-# ya.make files by maintainers. Any complex modifications which can't be ported back to the
-# original buildsystem will not be accepted.
-
-
-
-add_library(actors-wilson-protos INTERFACE)
-target_link_libraries(actors-wilson-protos INTERFACE
- contrib-libs-cxxsupp
- yutil
- contrib-libs-opentelemetry-proto
-)
diff --git a/library/cpp/actors/wilson/protos/ya.make b/library/cpp/actors/wilson/protos/ya.make
deleted file mode 100644
index e9db290efd..0000000000
--- a/library/cpp/actors/wilson/protos/ya.make
+++ /dev/null
@@ -1,12 +0,0 @@
-PROTO_LIBRARY()
-
- PEERDIR(
- contrib/libs/opentelemetry-proto
- )
-
- EXCLUDE_TAGS(
- GO_PROTO
- JAVA_PROTO
- )
-
-END()
diff --git a/library/cpp/actors/wilson/wilson_event.cpp b/library/cpp/actors/wilson/wilson_event.cpp
deleted file mode 100644
index ad51550d91..0000000000
--- a/library/cpp/actors/wilson/wilson_event.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "wilson_event.h"
-
-namespace NWilson {
-}
diff --git a/library/cpp/actors/wilson/wilson_event.h b/library/cpp/actors/wilson/wilson_event.h
deleted file mode 100644
index 4b6a7612c0..0000000000
--- a/library/cpp/actors/wilson/wilson_event.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include "wilson_trace.h"
-
-#include <library/cpp/string_utils/base64/base64.h>
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/log.h>
-
-namespace NWilson {
-
- // stub for NBS
- template<typename TActorSystem>
- inline bool TraceEnabled(const TActorSystem&) {
- return false;
- }
-
- template<typename TActorSystem, typename TEvent>
- inline void TraceEvent(const TActorSystem&, TTraceId*, TEvent&&, TInstant)
- {}
-
-} // NWilson
diff --git a/library/cpp/actors/wilson/wilson_profile_span.cpp b/library/cpp/actors/wilson/wilson_profile_span.cpp
deleted file mode 100644
index e908ed2b8a..0000000000
--- a/library/cpp/actors/wilson/wilson_profile_span.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "wilson_profile_span.h"
-#include <library/cpp/json/writer/json.h>
-
-namespace NWilson {
-
-void TProfileSpan::AddMax(const TString& eventId, const TString& /*info*/) {
- if (!Enabled) {
- return;
- }
- auto it = PairInstances.find(eventId);
- if (it == PairInstances.end()) {
- PairInstances.emplace(eventId, TMinMaxPair::BuildMax(Now()));
- } else {
- it->second.AddMax(Now());
- }
-}
-
-void TProfileSpan::AddMin(const TString& eventId, const TString& /*info*/) {
- if (!Enabled) {
- return;
- }
- auto it = PairInstances.find(eventId);
- if (it == PairInstances.end()) {
- PairInstances.emplace(eventId, TMinMaxPair::BuildMin(Now()));
- } else {
- it->second.AddMin(Now());
- }
-}
-
-TProfileSpan::TProfileSpan(const ui8 verbosity, TTraceId parentId, std::optional<TString> name)
- : TBase(verbosity, std::move(parentId), name, NWilson::EFlags::AUTO_END)
-{
-
-}
-
-TProfileSpan::~TProfileSpan() {
- if (Enabled && (ResultTimes.GetMapSafe().size() || PairInstances.size())) {
- TBase::Attribute("profile", ProfileToString());
- }
-}
-
-NWilson::TProfileSpan TProfileSpan::BuildChildrenSpan(std::optional<TString> name, const ui8 verbosity) const {
- TTraceId parentTraceId = TBase::GetTraceId();
- const ui8 newVerbosity = verbosity ? verbosity : parentTraceId.GetVerbosity();
- return TProfileSpan(newVerbosity, std::move(parentTraceId), name);
-}
-
-TString TProfileSpan::ProfileToString() const {
- if (!Enabled) {
- return "DISABLED";
- }
- TStringBuilder sb;
- FlushNoGuards();
- {
- NJsonWriter::TBuf sout;
- ResultTimes.InsertValue("-current_guards_count", CurrentJsonPath.size());
- ResultTimes.InsertValue("-duration", (Now() - StartTime).MicroSeconds() * 0.000001);
- sout.WriteJsonValue(&ResultTimes, true, EFloatToStringMode::PREC_POINT_DIGITS, 6);
- sb << sout.Str();
- }
- sb << ";";
- sb << "Pairs:{";
- for (auto&& i : PairInstances) {
- sb << i.first << ":" << i.second.ToString() << ";";
- }
- sb << "}";
- return sb;
-}
-
-void TProfileSpan::FlushNoGuards() const {
- if (!Enabled) {
- return;
- }
- if (CurrentJsonPath.empty()) {
- NJson::TJsonValue* currentNodeOutside;
- if (!ResultTimes.GetValuePointer("--outside_duration", &currentNodeOutside)) {
- currentNodeOutside = &ResultTimes.InsertValue("--outside_duration", 0);
- currentNodeOutside->SetType(NJson::JSON_DOUBLE);
- }
- currentNodeOutside->SetValue(currentNodeOutside->GetDoubleRobust() + (Now() - LastNoGuards).MicroSeconds() * 0.000001);
- LastNoGuards = Now();
- }
-}
-
-NWilson::TProfileSpan::TMinMaxPair TProfileSpan::TMinMaxPair::BuildMin(const TInstant value) {
- TMinMaxPair result;
- result.MinMinInstance = value;
- result.MaxMinInstance = value;
- return result;
-}
-
-NWilson::TProfileSpan::TMinMaxPair TProfileSpan::TMinMaxPair::BuildMax(const TInstant value) {
- TMinMaxPair result;
- result.MaxInstance = value;
- return result;
-}
-
-void TProfileSpan::TMinMaxPair::AddMax(const TInstant instance) {
- if (!MaxInstance) {
- MaxInstance = instance;
- } else {
- MaxInstance = Max(*MaxInstance, instance);
- }
-}
-
-void TProfileSpan::TMinMaxPair::AddMin(const TInstant instance) {
- if (!MinMinInstance) {
- MinMinInstance = instance;
- } else {
- MinMinInstance = Min(*MinMinInstance, instance);
- }
- if (!MaxMinInstance) {
- MaxMinInstance = instance;
- } else {
- MaxMinInstance = Max(*MaxMinInstance, instance);
- }
-}
-
-TString TProfileSpan::TMinMaxPair::ToString() const {
- TStringBuilder sb;
- sb << "[";
- if (MinMinInstance) {
- sb << MinMinInstance->MicroSeconds();
- } else {
- sb << "UNDEFINED";
- }
- sb << "-";
- if (MaxMinInstance) {
- sb << MaxMinInstance->MicroSeconds();
- } else {
- sb << "UNDEFINED";
- }
- sb << ",";
- if (MaxInstance) {
- sb << MaxInstance->MicroSeconds();
- } else {
- sb << "UNDEFINED";
- }
- if (MaxInstance && MinMinInstance) {
- sb << ",";
- sb << *MaxInstance - *MaxMinInstance << "-" << *MaxInstance - *MinMinInstance;
- }
- sb << "]";
- return sb;
-}
-
-TProfileSpan::TGuard::~TGuard() {
- if (!Owner.Enabled) {
- return;
- }
- Y_ABORT_UNLESS(CurrentNodeDuration->IsDouble());
- CurrentNodeDuration->SetValue((Now() - Start).MicroSeconds() * 0.000001 + CurrentNodeDuration->GetDoubleRobust());
- Y_ABORT_UNLESS(Owner.CurrentJsonPath.size());
- Owner.CurrentJsonPath.pop_back();
- if (Owner.CurrentJsonPath.empty()) {
- Owner.LastNoGuards = Now();
- }
-}
-
-TProfileSpan::TGuard::TGuard(const TString& event, TProfileSpan& owner, const TString& /*info*/)
- : Owner(owner) {
- if (!Owner.Enabled) {
- return;
- }
- Owner.FlushNoGuards();
- NJson::TJsonValue* currentNode = Owner.CurrentJsonPath.empty() ? &Owner.ResultTimes : Owner.CurrentJsonPath.back();
- NJson::TJsonValue* currentNodeParent;
- if (!currentNode->GetValuePointer(event, &currentNodeParent)) {
- currentNodeParent = &currentNode->InsertValue(event, NJson::JSON_MAP);
- }
- Owner.CurrentJsonPath.emplace_back(currentNodeParent);
- if (!currentNodeParent->GetValuePointer("--duration", &CurrentNodeDuration)) {
- CurrentNodeDuration = &currentNodeParent->InsertValue("--duration", 0);
- CurrentNodeDuration->SetType(NJson::JSON_DOUBLE);
- }
-}
-
-} // NWilson
diff --git a/library/cpp/actors/wilson/wilson_profile_span.h b/library/cpp/actors/wilson/wilson_profile_span.h
deleted file mode 100644
index f12747e4ac..0000000000
--- a/library/cpp/actors/wilson/wilson_profile_span.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#pragma once
-#include "wilson_span.h"
-#include <library/cpp/json/writer/json_value.h>
-
-namespace NWilson {
-
-class TProfileSpan: public TSpan {
-private:
- using TBase = TSpan;
- class TMinMaxPair {
- private:
- std::optional<TInstant> MinMinInstance;
- std::optional<TInstant> MaxMinInstance;
- std::optional<TInstant> MaxInstance;
- public:
- static TMinMaxPair BuildMin(const TInstant value);
- static TMinMaxPair BuildMax(const TInstant value);
- void AddMax(const TInstant instance);
- void AddMin(const TInstant instance);
- TString ToString() const;
- };
- mutable NJson::TJsonValue ResultTimes = NJson::JSON_MAP;
- std::map<TString, TMinMaxPair> PairInstances;
- std::vector<NJson::TJsonValue*> CurrentJsonPath;
- mutable TInstant LastNoGuards = Now();
- const TInstant StartTime = Now();
- bool Enabled = true;
-
- void FlushNoGuards() const;
- TProfileSpan() = default;
-public:
- TProfileSpan(const ui8 verbosity, TTraceId parentId, std::optional<TString> name);
- ~TProfileSpan();
-
- TProfileSpan BuildChildrenSpan(std::optional<TString> name, const ui8 verbosity = 0) const;
-
- using TBase::TBase;
- TString ProfileToString() const;
-
- TProfileSpan& SetEnabled(const bool value) {
- Enabled = value;
- return *this;
- }
-
- class TGuard {
- private:
- TProfileSpan& Owner;
- const TInstant Start = Now();
- NJson::TJsonValue* CurrentNodeDuration;
- public:
- TGuard(const TString& event, TProfileSpan& owner, const TString& info);
- ~TGuard();
- };
-
- template <class TEventId, class T = TString>
- TGuard StartStackTimeGuard(const TEventId event, const T& info = Default<T>()) {
- return TGuard(::ToString(event), *this, ::ToString(info));
- }
-
- template <class TEventId, class T = TString>
- void AddMin(const TEventId event, const T& info = Default<T>()) {
- AddMin(::ToString(event), ::ToString(info));
- }
-
- template <class TEventId, class T = TString>
- void AddMax(const TEventId event, const T& info = Default<T>()) {
- AddMax(::ToString(event), ::ToString(info));
- }
-
- void AddMin(const TString& eventId, const TString& info);
- void AddMax(const TString& eventId, const TString& info);
-
-};
-
-} // NWilson
diff --git a/library/cpp/actors/wilson/wilson_span.cpp b/library/cpp/actors/wilson/wilson_span.cpp
deleted file mode 100644
index dcd458be7c..0000000000
--- a/library/cpp/actors/wilson/wilson_span.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "wilson_span.h"
-#include "wilson_uploader.h"
-#include <library/cpp/actors/core/log.h>
-#include <google/protobuf/text_format.h>
-
-namespace NWilson {
-
- using namespace NActors;
-
- void SerializeValue(TAttributeValue value, NCommonProto::AnyValue *pb) {
- switch (value.index()) {
- case 0:
- pb->set_string_value(std::get<0>(std::move(value)));
- break;
-
- case 1:
- pb->set_bool_value(std::get<1>(value));
- break;
-
- case 2:
- pb->set_int_value(std::get<2>(value));
- break;
-
- case 3:
- pb->set_double_value(std::get<3>(std::move(value)));
- break;
-
- case 4: {
- auto *array = pb->mutable_array_value();
- for (auto&& item : std::get<4>(std::move(value))) {
- SerializeValue(std::move(item), array->add_values());
- }
- break;
- }
-
- case 5: {
- auto *kv = pb->mutable_kvlist_value();
- for (auto&& [key, value] : std::get<5>(std::move(value))) {
- SerializeKeyValue(std::move(key), std::move(value), kv->add_values());
- }
- break;
- }
-
- case 6:
- pb->set_bytes_value(std::get<6>(std::move(value)));
- break;
- }
- }
-
- void SerializeKeyValue(TString key, TAttributeValue value, NCommonProto::KeyValue *pb) {
- pb->set_key(std::move(key));
- SerializeValue(std::move(value), pb->mutable_value());
- }
-
- void TSpan::Send() {
- if (TlsActivationContext) {
- TActivationContext::Send(new IEventHandle(MakeWilsonUploaderId(), {}, new TEvWilson(&Data->Span)));
- }
- Data->Sent = true;
- }
-
-} // NWilson
diff --git a/library/cpp/actors/wilson/wilson_span.h b/library/cpp/actors/wilson/wilson_span.h
deleted file mode 100644
index 2ebf837cda..0000000000
--- a/library/cpp/actors/wilson/wilson_span.h
+++ /dev/null
@@ -1,244 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/actorsystem.h>
-#include <opentelemetry/proto/trace/v1/trace.pb.h>
-#include <util/generic/hash.h>
-#include <util/datetime/cputimer.h>
-
-#include "wilson_trace.h"
-
-namespace NWilson {
-
- enum class ERelation {
- FollowsFrom,
- ChildOf,
- };
-
- namespace NTraceProto = opentelemetry::proto::trace::v1;
- namespace NCommonProto = opentelemetry::proto::common::v1;
-
- struct TArrayValue;
- struct TKeyValueList;
- struct TBytes;
-
- using TAttributeValue = std::variant<
- TString,
- bool,
- i64,
- double,
- TArrayValue,
- TKeyValueList,
- TBytes
- >;
-
- struct TArrayValue : std::vector<TAttributeValue> {};
- struct TKeyValueList : THashMap<TString, TAttributeValue> {};
- struct TBytes : TString {};
-
- void SerializeKeyValue(TString key, TAttributeValue value, NCommonProto::KeyValue *pb);
-
- enum class EFlags : ui32 {
- NONE = 0,
- AUTO_END = 1,
- };
-
- Y_DECLARE_FLAGS(TFlags, EFlags);
- Y_DECLARE_OPERATORS_FOR_FLAGS(TFlags);
-
- class TSpan {
- struct TData {
- const TInstant StartTime;
- const ui64 StartCycles;
- const TTraceId TraceId;
- NTraceProto::Span Span;
- TFlags Flags;
- int UncaughtExceptions = std::uncaught_exceptions();
- bool Sent = false;
- bool Ignored = false;
-
- TData(TInstant startTime, ui64 startCycles, TTraceId traceId, TFlags flags)
- : StartTime(startTime)
- , StartCycles(startCycles)
- , TraceId(std::move(traceId))
- , Flags(flags)
- {}
-
- ~TData() {
- Y_DEBUG_ABORT_UNLESS(Sent || Ignored);
- }
- };
-
- std::unique_ptr<TData> Data;
-
- public:
- TSpan() = default;
- TSpan(const TSpan&) = delete;
- TSpan(TSpan&&) = default;
-
- TSpan(ui8 verbosity, TTraceId parentId, std::optional<TString> name, TFlags flags = EFlags::NONE)
- : Data(parentId
- ? std::make_unique<TData>(TInstant::Now(), GetCycleCount(), parentId.Span(verbosity), flags)
- : nullptr)
- {
- if (Y_UNLIKELY(*this)) {
- if (verbosity <= parentId.GetVerbosity()) {
- if (!parentId.IsRoot()) {
- Data->Span.set_parent_span_id(parentId.GetSpanIdPtr(), parentId.GetSpanIdSize());
- }
- Data->Span.set_start_time_unix_nano(Data->StartTime.NanoSeconds());
- Data->Span.set_kind(opentelemetry::proto::trace::v1::Span::SPAN_KIND_INTERNAL);
-
- if (name) {
- Name(std::move(*name));
- }
-
- Attribute("node_id", NActors::TActivationContext::ActorSystem()->NodeId);
- } else {
- Data->Ignored = true; // ignore this span due to verbosity mismatch, still allowing child spans to be created
- }
- }
- }
-
- ~TSpan() {
- if (Y_UNLIKELY(*this)) {
- if (std::uncaught_exceptions() != Data->UncaughtExceptions) {
- EndError("span terminated due to stack unwinding");
- } else if (Data->Flags & EFlags::AUTO_END) {
- End();
- } else {
- EndError("unterminated span");
- }
- }
- }
-
- TSpan& operator =(const TSpan&) = delete;
-
- TSpan& operator =(TSpan&& other) {
- if (this != &other) {
- if (Y_UNLIKELY(*this)) {
- EndError("TSpan instance incorrectly overwritten");
- }
- Data = std::exchange(other.Data, nullptr);
- }
- return *this;
- }
-
- explicit operator bool() const {
- return Data && !Data->Sent && !Data->Ignored;
- }
-
- TSpan& EnableAutoEnd() {
- if (Y_UNLIKELY(*this)) {
- Data->Flags |= EFlags::AUTO_END;
- } else {
- VerifyNotSent();
- }
- return *this;
- }
-
- TSpan& Relation(ERelation /*relation*/) {
- if (Y_UNLIKELY(*this)) {
- // update relation in data somehow
- } else {
- VerifyNotSent();
- }
- return *this;
- }
-
- TSpan& Name(TString name) {
- if (Y_UNLIKELY(*this)) {
- Data->Span.set_name(std::move(name));
- } else {
- VerifyNotSent();
- }
- return *this;
- }
-
- TSpan& Attribute(TString name, TAttributeValue value) {
- if (Y_UNLIKELY(*this)) {
- SerializeKeyValue(std::move(name), std::move(value), Data->Span.add_attributes());
- } else {
- VerifyNotSent();
- }
- return *this;
- }
-
- TSpan& Event(TString name, TKeyValueList attributes) {
- if (Y_UNLIKELY(*this)) {
- auto *event = Data->Span.add_events();
- event->set_time_unix_nano(TimeUnixNano());
- event->set_name(std::move(name));
- for (auto&& [key, value] : attributes) {
- SerializeKeyValue(std::move(key), std::move(value), event->add_attributes());
- }
- } else {
- VerifyNotSent();
- }
- return *this;
- }
-
- TSpan& Link(const TTraceId& traceId, TKeyValueList attributes) {
- if (Y_UNLIKELY(*this)) {
- auto *link = Data->Span.add_links();
- link->set_trace_id(traceId.GetTraceIdPtr(), traceId.GetTraceIdSize());
- link->set_span_id(traceId.GetSpanIdPtr(), traceId.GetSpanIdSize());
- for (auto&& [key, value] : attributes) {
- SerializeKeyValue(std::move(key), std::move(value), link->add_attributes());
- }
- } else {
- VerifyNotSent();
- }
- return *this;
- }
-
- void EndOk() {
- if (Y_UNLIKELY(*this)) {
- auto *status = Data->Span.mutable_status();
- status->set_code(NTraceProto::Status::STATUS_CODE_OK);
- End();
- } else {
- VerifyNotSent();
- }
- }
-
- void EndError(TString error) {
- if (Y_UNLIKELY(*this)) {
- auto *status = Data->Span.mutable_status();
- status->set_code(NTraceProto::Status::STATUS_CODE_ERROR);
- status->set_message(std::move(error));
- End();
- } else {
- VerifyNotSent();
- }
- }
-
- void End() {
- if (Y_UNLIKELY(*this)) {
- Data->Span.set_trace_id(Data->TraceId.GetTraceIdPtr(), Data->TraceId.GetTraceIdSize());
- Data->Span.set_span_id(Data->TraceId.GetSpanIdPtr(), Data->TraceId.GetSpanIdSize());
- Data->Span.set_end_time_unix_nano(TimeUnixNano());
- Send();
- } else {
- VerifyNotSent();
- }
- }
-
- TTraceId GetTraceId() const {
- return Data ? TTraceId(Data->TraceId) : TTraceId();
- }
-
- private:
- void Send();
-
- ui64 TimeUnixNano() const {
- const TInstant now = Data->StartTime + CyclesToDuration(GetCycleCount() - Data->StartCycles);
- return now.NanoSeconds();
- }
-
- void VerifyNotSent() {
- Y_DEBUG_ABORT_UNLESS(!Data || !Data->Sent, "span has been ended");
- }
- };
-
-} // NWilson
diff --git a/library/cpp/actors/wilson/wilson_trace.cpp b/library/cpp/actors/wilson/wilson_trace.cpp
deleted file mode 100644
index 73bed31da3..0000000000
--- a/library/cpp/actors/wilson/wilson_trace.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "wilson_trace.h"
-
-namespace NWilson {
-}
diff --git a/library/cpp/actors/wilson/wilson_trace.h b/library/cpp/actors/wilson/wilson_trace.h
deleted file mode 100644
index 41a6505134..0000000000
--- a/library/cpp/actors/wilson/wilson_trace.h
+++ /dev/null
@@ -1,234 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/monotonic.h>
-#include <library/cpp/actors/protos/actors.pb.h>
-
-#include <library/cpp/string_utils/base64/base64.h>
-
-#include <util/stream/output.h>
-#include <util/random/random.h>
-#include <util/random/fast.h>
-
-#include <util/string/printf.h>
-
-#include <array>
-
-namespace NWilson {
- class TTraceId {
- using TTrace = std::array<ui64, 2>;
-
- TTrace TraceId; // Random id of topmost client request
- ui64 SpanId;
- union {
- struct {
- ui32 Verbosity : 4;
- ui32 TimeToLive : 12;
- };
- ui32 Raw;
- };
-
- private:
- TTraceId(TTrace traceId, ui64 spanId, ui8 verbosity, ui32 timeToLive)
- : TraceId(traceId)
- {
- if (timeToLive == Max<ui32>()) {
- timeToLive = 4095;
- }
- Y_ABORT_UNLESS(verbosity <= 15);
- Y_ABORT_UNLESS(timeToLive <= 4095);
- SpanId = spanId;
- Verbosity = verbosity;
- TimeToLive = timeToLive;
- }
-
- static TTrace GenerateTraceId() {
- for (;;) {
- TTrace res;
- ui32 *p = reinterpret_cast<ui32*>(res.data());
-
- TReallyFastRng32 rng(RandomNumber<ui64>());
- p[0] = rng();
- p[1] = rng();
- p[2] = rng();
- p[3] = rng();
-
- if (res[0] || res[1]) {
- return res;
- }
- }
- }
-
- static ui64 GenerateSpanId() {
- for (;;) {
- if (const ui64 res = RandomNumber<ui64>(); res) { // SpanId can't be zero
- return res;
- }
- }
- }
-
- public:
- using TSerializedTraceId = char[sizeof(TTrace) + sizeof(ui64) + sizeof(ui32)];
-
- public:
- TTraceId(ui64) // NBS stub
- : TTraceId()
- {}
-
- TTraceId() {
- TraceId.fill(0);
- SpanId = 0;
- Raw = 0;
- }
-
- explicit TTraceId(TTrace traceId)
- : TraceId(traceId)
- {
- SpanId = 0;
- Raw = 0;
- }
-
- // allow move semantic
- TTraceId(TTraceId&& other)
- : TraceId(other.TraceId)
- , SpanId(other.SpanId)
- , Raw(other.Raw)
- {
- other.TraceId.fill(0);
- other.SpanId = 1; // make it explicitly invalid
- other.Raw = 0;
- }
-
- // explicit copy
- explicit TTraceId(const TTraceId& other)
- : TraceId(other.TraceId)
- , SpanId(other.SpanId)
- , Raw(other.Raw)
- {
- // validate trace id only when we are making a copy
- other.Validate();
- }
-
- TTraceId(const TSerializedTraceId& in) {
- const char *p = in;
- memcpy(TraceId.data(), p, sizeof(TraceId));
- p += sizeof(TraceId);
- memcpy(&SpanId, p, sizeof(SpanId));
- p += sizeof(SpanId);
- memcpy(&Raw, p, sizeof(Raw));
- p += sizeof(Raw);
- Y_DEBUG_ABORT_UNLESS(p - in == sizeof(TSerializedTraceId));
- }
-
- TTraceId(const NActorsProto::TTraceId& pb)
- : TTraceId()
- {
- if (pb.HasData()) {
- const auto& data = pb.GetData();
- if (data.size() == sizeof(TSerializedTraceId)) {
- *this = *reinterpret_cast<const TSerializedTraceId*>(data.data());
- }
- }
- }
-
- void Serialize(TSerializedTraceId *out) const {
- char *p = *out;
- memcpy(p, TraceId.data(), sizeof(TraceId));
- p += sizeof(TraceId);
- memcpy(p, &SpanId, sizeof(SpanId));
- p += sizeof(SpanId);
- memcpy(p, &Raw, sizeof(Raw));
- p += sizeof(Raw);
- Y_DEBUG_ABORT_UNLESS(p - *out == sizeof(TSerializedTraceId));
- }
-
- void Serialize(NActorsProto::TTraceId *pb) const {
- if (*this) {
- TSerializedTraceId data;
- Serialize(&data);
- pb->SetData(reinterpret_cast<const char*>(&data), sizeof(data));
- }
- }
-
- TTraceId& operator=(TTraceId&& other) {
- if (this != &other) {
- TraceId = other.TraceId;
- SpanId = other.SpanId;
- Raw = other.Raw;
- other.TraceId.fill(0);
- other.SpanId = 1; // make it explicitly invalid
- other.Raw = 0;
- }
- return *this;
- }
-
- // do not allow implicit copy of trace id
- TTraceId& operator=(const TTraceId& other) = delete;
-
- static TTraceId NewTraceId(ui8 verbosity, ui32 timeToLive) {
- return TTraceId(GenerateTraceId(), 0, verbosity, timeToLive);
- }
-
- static TTraceId NewTraceIdThrottled(ui8 verbosity, ui32 timeToLive, std::atomic<NActors::TMonotonic>& counter,
- NActors::TMonotonic now, TDuration periodBetweenSamples) {
- static_assert(std::atomic<NActors::TMonotonic>::is_always_lock_free);
- for (;;) {
- NActors::TMonotonic ts = counter.load();
- if (now < ts) {
- return {};
- } else if (counter.compare_exchange_strong(ts, now + periodBetweenSamples)) {
- return NewTraceId(verbosity, timeToLive);
- }
- }
- }
-
- static TTraceId NewTraceId() { // NBS stub
- return TTraceId();
- }
-
- TTraceId Span(ui8 verbosity) const {
- Validate();
- if (!*this || !TimeToLive) {
- return TTraceId();
- } else if (verbosity <= Verbosity) {
- return TTraceId(TraceId, GenerateSpanId(), Verbosity, TimeToLive - 1);
- } else {
- return TTraceId(TraceId, SpanId, Verbosity, TimeToLive - 1);
- }
- }
-
- TTraceId Span() const { // compatibility stub
- return {};
- }
-
- // Check if request tracing is enabled
- explicit operator bool() const {
- return TraceId[0] || TraceId[1];
- }
-
- bool IsRoot() const {
- return !SpanId;
- }
-
- friend bool operator==(const TTraceId& x, const TTraceId& y) {
- return x.TraceId == y.TraceId && x.SpanId == y.SpanId && x.Raw == y.Raw;
- }
-
- ui8 GetVerbosity() const {
- return Verbosity;
- }
-
- const void *GetTraceIdPtr() const { return TraceId.data(); }
- static constexpr size_t GetTraceIdSize() { return sizeof(TTrace); }
- const void *GetSpanIdPtr() const { return &SpanId; }
- static constexpr size_t GetSpanIdSize() { return sizeof(ui64); }
-
- void Validate() const {
- Y_DEBUG_ABORT_UNLESS(*this || !SpanId);
- }
-
- // for compatibility with NBS
- TTraceId Clone() const { return NWilson::TTraceId(*this); }
- ui64 GetTraceId() const { return 0; }
- void OutputSpanId(IOutputStream&) const {}
- };
-}
diff --git a/library/cpp/actors/wilson/wilson_uploader.cpp b/library/cpp/actors/wilson/wilson_uploader.cpp
deleted file mode 100644
index 3599d66809..0000000000
--- a/library/cpp/actors/wilson/wilson_uploader.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-#include "wilson_uploader.h"
-#include <library/cpp/actors/core/actor_bootstrapped.h>
-#include <library/cpp/actors/core/hfunc.h>
-#include <library/cpp/actors/core/log.h>
-#include <opentelemetry/proto/collector/trace/v1/trace_service.pb.h>
-#include <opentelemetry/proto/collector/trace/v1/trace_service.grpc.pb.h>
-#include <util/stream/file.h>
-#include <util/string/hex.h>
-#include <grpc++/grpc++.h>
-#include <chrono>
-
-namespace NWilson {
-
- using namespace NActors;
-
- namespace NServiceProto = opentelemetry::proto::collector::trace::v1;
- namespace NTraceProto = opentelemetry::proto::trace::v1;
-
- namespace {
-
- class TWilsonUploader
- : public TActorBootstrapped<TWilsonUploader>
- {
- TString Host;
- ui16 Port;
- TString RootCA;
- TString ServiceName;
-
- std::shared_ptr<grpc::Channel> Channel;
- std::unique_ptr<NServiceProto::TraceService::Stub> Stub;
- grpc::CompletionQueue CQ;
-
- std::unique_ptr<grpc::ClientContext> Context;
- std::unique_ptr<grpc::ClientAsyncResponseReader<NServiceProto::ExportTraceServiceResponse>> Reader;
- NServiceProto::ExportTraceServiceResponse Response;
- grpc::Status Status;
-
- struct TSpanQueueItem {
- TMonotonic ExpirationTimestamp;
- NTraceProto::Span Span;
- ui32 Size;
- };
-
- std::deque<TSpanQueueItem> Spans;
- ui64 SpansSize = 0;
- TMonotonic NextSendTimestamp;
- ui32 MaxSpansAtOnce = 25;
- ui32 MaxSpansPerSecond = 10;
- TDuration MaxSpanTimeInQueue = TDuration::Seconds(60);
-
- bool WakeupScheduled = false;
-
- public:
- TWilsonUploader(TString host, ui16 port, TString rootCA, TString serviceName)
- : Host(std::move(host))
- , Port(std::move(port))
- , RootCA(std::move(rootCA))
- , ServiceName(std::move(serviceName))
- {}
-
- ~TWilsonUploader() {
- CQ.Shutdown();
- }
-
- static constexpr char ActorName[] = "WILSON_UPLOADER_ACTOR";
-
- void Bootstrap() {
- Become(&TThis::StateFunc);
-
- Channel = grpc::CreateChannel(TStringBuilder() << Host << ":" << Port, RootCA ? grpc::SslCredentials({
- .pem_root_certs = TFileInput(RootCA).ReadAll(),
- }) : grpc::InsecureChannelCredentials());
- Stub = NServiceProto::TraceService::NewStub(Channel);
-
- LOG_INFO_S(*TlsActivationContext, 430 /* NKikimrServices::WILSON */, "TWilsonUploader::Bootstrap");
- }
-
- void Handle(TEvWilson::TPtr ev) {
- if (SpansSize >= 100'000'000) {
- LOG_ERROR_S(*TlsActivationContext, 430 /* NKikimrServices::WILSON */, "dropped span due to overflow");
- } else {
- const TMonotonic expirationTimestamp = TActivationContext::Monotonic() + MaxSpanTimeInQueue;
- auto& span = ev->Get()->Span;
- const ui32 size = span.ByteSizeLong();
- Spans.push_back(TSpanQueueItem{expirationTimestamp, std::move(span), size});
- SpansSize += size;
- CheckIfDone();
- TryToSend();
- }
- }
-
- void TryToSend() {
- const TMonotonic now = TActivationContext::Monotonic();
-
- ui32 numSpansDropped = 0;
- while (!Spans.empty()) {
- const TSpanQueueItem& item = Spans.front();
- if (item.ExpirationTimestamp <= now) {
- SpansSize -= item.Size;
- Spans.pop_front();
- ++numSpansDropped;
- } else {
- break;
- }
- }
-
- if (numSpansDropped) {
- LOG_ERROR_S(*TlsActivationContext, 430 /* NKikimrServices::WILSON */,
- "dropped " << numSpansDropped << " span(s) due to expiration");
- }
-
- if (Context || Spans.empty()) {
- return;
- } else if (now < NextSendTimestamp) {
- ScheduleWakeup(NextSendTimestamp);
- return;
- }
-
- NServiceProto::ExportTraceServiceRequest request;
- auto *rspan = request.add_resource_spans();
- auto *serviceNameAttr = rspan->mutable_resource()->add_attributes();
- serviceNameAttr->set_key("service.name");
- serviceNameAttr->mutable_value()->set_string_value(ServiceName);
- auto *sspan = rspan->add_scope_spans();
-
- NextSendTimestamp = now;
- for (ui32 i = 0; i < MaxSpansAtOnce && !Spans.empty(); ++i, Spans.pop_front()) {
- auto& item = Spans.front();
- auto& s = item.Span;
-
- LOG_DEBUG_S(*TlsActivationContext, 430 /* NKikimrServices::WILSON */, "exporting span"
- << " TraceId# " << HexEncode(s.trace_id())
- << " SpanId# " << HexEncode(s.span_id())
- << " ParentSpanId# " << HexEncode(s.parent_span_id())
- << " Name# " << s.name());
-
- SpansSize -= item.Size;
- s.Swap(sspan->add_spans());
- NextSendTimestamp += TDuration::MicroSeconds(1'000'000 / MaxSpansPerSecond);
- }
-
- Context = std::make_unique<grpc::ClientContext>();
- Reader = Stub->AsyncExport(Context.get(), std::move(request), &CQ);
- Reader->Finish(&Response, &Status, nullptr);
- }
-
- void CheckIfDone() {
- if (Context) {
- void *tag;
- bool ok;
- if (CQ.AsyncNext(&tag, &ok, std::chrono::system_clock::now()) == grpc::CompletionQueue::GOT_EVENT) {
- if (!Status.ok()) {
- LOG_ERROR_S(*TlsActivationContext, 430 /* NKikimrServices::WILSON */,
- "failed to commit traces: " << Status.error_message());
- }
-
- Reader.reset();
- Context.reset();
- } else {
- ScheduleWakeup(TDuration::MilliSeconds(100));
- }
- }
- }
-
- template<typename T>
- void ScheduleWakeup(T&& deadline) {
- if (!WakeupScheduled) {
- TActivationContext::Schedule(deadline, new IEventHandle(TEvents::TSystem::Wakeup, 0, SelfId(), {},
- nullptr, 0));
- WakeupScheduled = true;
- }
- }
-
- void HandleWakeup() {
- Y_ABORT_UNLESS(WakeupScheduled);
- WakeupScheduled = false;
- CheckIfDone();
- TryToSend();
- }
-
- STRICT_STFUNC(StateFunc,
- hFunc(TEvWilson, Handle);
- cFunc(TEvents::TSystem::Wakeup, HandleWakeup);
- );
- };
-
- } // anonymous
-
- IActor *CreateWilsonUploader(TString host, ui16 port, TString rootCA, TString serviceName) {
- return new TWilsonUploader(std::move(host), port, std::move(rootCA), std::move(serviceName));
- }
-
-} // NWilson
diff --git a/library/cpp/actors/wilson/wilson_uploader.h b/library/cpp/actors/wilson/wilson_uploader.h
deleted file mode 100644
index 86c23ccefe..0000000000
--- a/library/cpp/actors/wilson/wilson_uploader.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <library/cpp/actors/core/actor.h>
-#include <library/cpp/actors/core/event_local.h>
-#include <library/cpp/actors/core/events.h>
-#include <opentelemetry/proto/trace/v1/trace.pb.h>
-
-namespace NWilson {
-
- struct TEvWilson : NActors::TEventLocal<TEvWilson, NActors::TEvents::TSystem::Wilson> {
- opentelemetry::proto::trace::v1::Span Span;
-
- TEvWilson(opentelemetry::proto::trace::v1::Span *span) {
- Span.Swap(span);
- }
- };
-
- inline NActors::TActorId MakeWilsonUploaderId() {
- return NActors::TActorId(0, TStringBuf("WilsonUpload", 12));
- }
-
- NActors::IActor *CreateWilsonUploader(TString host, ui16 port, TString rootCA, TString serviceName);
-
-} // NWilson
diff --git a/library/cpp/actors/wilson/ya.make b/library/cpp/actors/wilson/ya.make
deleted file mode 100644
index 0dc8ba79ad..0000000000
--- a/library/cpp/actors/wilson/ya.make
+++ /dev/null
@@ -1,21 +0,0 @@
-LIBRARY()
-
-SRCS(
- wilson_event.cpp
- wilson_span.cpp
- wilson_profile_span.cpp
- wilson_trace.cpp
- wilson_uploader.cpp
-)
-
-PEERDIR(
- library/cpp/actors/core
- library/cpp/actors/protos
- library/cpp/actors/wilson/protos
-)
-
-END()
-
-RECURSE(
- protos
-)
diff --git a/library/cpp/actors/ya.make b/library/cpp/actors/ya.make
deleted file mode 100644
index 00d7801798..0000000000
--- a/library/cpp/actors/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-RECURSE(
- log_backend
- core
- cppcoro
- dnsresolver
- examples
- interconnect
- memory_log
- helpers
- prof
- protos
- util
- wilson
- testlib
- http
-)
diff --git a/library/cpp/deprecated/autoarray/README.md b/library/cpp/deprecated/autoarray/README.md
deleted file mode 100644
index 1d83147cee..0000000000
--- a/library/cpp/deprecated/autoarray/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Pre-C++11 vector-like container.
-
-Just use std::vector. If you need to fill your vector with custom-constructed data, use reserve+emplace_back (but make sure that your elements are movable).
diff --git a/library/cpp/deprecated/autoarray/autoarray.cpp b/library/cpp/deprecated/autoarray/autoarray.cpp
deleted file mode 100644
index 15167f27f6..0000000000
--- a/library/cpp/deprecated/autoarray/autoarray.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "autoarray.h"
diff --git a/library/cpp/deprecated/autoarray/autoarray.h b/library/cpp/deprecated/autoarray/autoarray.h
deleted file mode 100644
index 2aa12c5916..0000000000
--- a/library/cpp/deprecated/autoarray/autoarray.h
+++ /dev/null
@@ -1,264 +0,0 @@
-#pragma once
-
-#include <util/system/compat.h>
-#include <util/system/yassert.h>
-#include <util/system/defaults.h>
-#include <util/system/sys_alloc.h>
-
-#include <util/generic/typetraits.h>
-#include <utility>
-
-#include <new>
-#include <util/generic/noncopyable.h>
-
-struct autoarray_getindex {
- autoarray_getindex() = default;
-};
-
-struct aarr_b0 {
- aarr_b0() = default;
-};
-
-struct aarr_nofill {
- aarr_nofill() = default;
-};
-
-template <typename T>
-struct ynd_type_traits {
- enum {
- empty_destructor = TTypeTraits<T>::IsPod,
- };
-};
-
-template <class T>
-class autoarray : TNonCopyable {
-protected:
- T* arr;
- size_t _size;
-
-private:
- void AllocBuf(size_t siz) {
- arr = nullptr;
- _size = 0;
- if (siz) {
- arr = (T*)y_allocate(sizeof(T) * siz);
- _size = siz;
- }
- }
-
-public:
- using value_type = T;
- using iterator = T*;
- using const_iterator = const T*;
-
- autoarray()
- : arr(nullptr)
- , _size(0)
- {
- }
- autoarray(size_t siz) {
- AllocBuf(siz);
- T* curr = arr;
- try {
- for (T* end = arr + _size; curr != end; ++curr)
- new (curr) T();
- } catch (...) {
- for (--curr; curr >= arr; --curr)
- curr->~T();
- y_deallocate(arr);
- throw;
- }
- }
- template <class A>
- explicit autoarray(size_t siz, A& fill) {
- AllocBuf(siz);
- T* curr = arr;
- try {
- for (T* end = arr + _size; curr != end; ++curr)
- new (curr) T(fill);
- } catch (...) {
- for (--curr; curr >= arr; --curr)
- curr->~T();
- y_deallocate(arr);
- throw;
- }
- }
- explicit autoarray(size_t siz, autoarray_getindex) {
- AllocBuf(siz);
- size_t nCurrent = 0;
- try {
- for (nCurrent = 0; nCurrent < _size; ++nCurrent)
- new (&arr[nCurrent]) T(nCurrent);
- } catch (...) {
- for (size_t n = 0; n < nCurrent; ++n)
- arr[n].~T();
- y_deallocate(arr);
- throw;
- }
- }
- explicit autoarray(size_t siz, aarr_b0) {
- AllocBuf(siz);
- memset(arr, 0, _size * sizeof(T));
- }
- explicit autoarray(size_t siz, aarr_nofill) {
- AllocBuf(siz);
- }
- template <class A>
- explicit autoarray(const A* fill, size_t siz) {
- AllocBuf(siz);
- size_t nCurrent = 0;
- try {
- for (nCurrent = 0; nCurrent < _size; ++nCurrent)
- new (&arr[nCurrent]) T(fill[nCurrent]);
- } catch (...) {
- for (size_t n = 0; n < nCurrent; ++n)
- arr[n].~T();
- y_deallocate(arr);
- throw;
- }
- }
- template <class A, class B>
- explicit autoarray(const A* fill, const B* cfill, size_t siz) {
- AllocBuf(siz);
- size_t nCurrent = 0;
- try {
- for (nCurrent = 0; nCurrent < _size; ++nCurrent)
- new (&arr[nCurrent]) T(fill[nCurrent], cfill);
- } catch (...) {
- for (size_t n = 0; n < nCurrent; ++n)
- arr[n].~T();
- y_deallocate(arr);
- throw;
- }
- }
- template <class A>
- explicit autoarray(const A* fill, size_t initsiz, size_t fullsiz) {
- AllocBuf(fullsiz);
- size_t nCurrent = 0;
- try {
- for (nCurrent = 0; nCurrent < ((initsiz < _size) ? initsiz : _size); ++nCurrent)
- new (&arr[nCurrent]) T(fill[nCurrent]);
- for (; nCurrent < _size; ++nCurrent)
- new (&arr[nCurrent]) T();
- } catch (...) {
- for (size_t n = 0; n < nCurrent; ++n)
- arr[n].~T();
- y_deallocate(arr);
- throw;
- }
- }
- template <class A>
- explicit autoarray(const A* fill, size_t initsiz, size_t fullsiz, const T& dummy) {
- AllocBuf(fullsiz);
- size_t nCurrent = 0;
- try {
- for (nCurrent = 0; nCurrent < ((initsiz < _size) ? initsiz : _size); ++nCurrent)
- new (&arr[nCurrent]) T(fill[nCurrent]);
- for (; nCurrent < _size; ++nCurrent)
- new (&arr[nCurrent]) T(dummy);
- } catch (...) {
- for (size_t n = 0; n < nCurrent; ++n)
- arr[n].~T();
- y_deallocate(arr);
- throw;
- }
- }
-
- template <class... R>
- explicit autoarray(size_t siz, R&&... fill) {
- AllocBuf(siz);
- T* curr = arr;
- try {
- for (T* end = arr + _size; curr != end; ++curr)
- new (curr) T(std::forward<R>(fill)...);
- } catch (...) {
- for (--curr; curr >= arr; --curr)
- curr->~T();
- y_deallocate(arr);
- throw;
- }
- }
- ~autoarray() {
- if (_size) {
- if (!ynd_type_traits<T>::empty_destructor)
- for (T *curr = arr, *end = arr + _size; curr != end; ++curr)
- curr->~T();
- y_deallocate(arr);
- }
- }
- T& operator[](size_t pos) {
- Y_ASSERT(pos < _size);
- return arr[pos];
- }
- const T& operator[](size_t pos) const {
- Y_ASSERT(pos < _size);
- return arr[pos];
- }
- size_t size() const {
- return _size;
- }
- void swap(autoarray& with) {
- T* tmp_arr = arr;
- size_t tmp_size = _size;
- arr = with.arr;
- _size = with._size;
- with.arr = tmp_arr;
- with._size = tmp_size;
- }
- void resize(size_t siz) {
- autoarray<T> tmp(arr, _size, siz);
- swap(tmp);
- }
- void resize(size_t siz, const T& dummy) {
- autoarray<T> tmp(arr, _size, siz, dummy);
- swap(tmp);
- }
- T* rawpointer() {
- return arr;
- }
- const T* operator~() const {
- return arr;
- }
- T* begin() {
- return arr;
- }
- T* end() {
- return arr + _size;
- }
- T& back() {
- Y_ASSERT(_size);
- return arr[_size - 1];
- }
- bool empty() const {
- return !_size;
- }
- bool operator!() const {
- return !_size;
- }
- size_t operator+() const {
- return _size;
- }
- const T* begin() const {
- return arr;
- }
- const T* end() const {
- return arr + _size;
- }
- const T& back() const {
- Y_ASSERT(_size);
- return arr[_size - 1];
- }
- //operator T*() { return arr; }
-};
-
-template <class T>
-inline bool operator==(const autoarray<T>& a, const autoarray<T>& b) {
- size_t count = a.size();
- if (count != b.size())
- return false;
- for (size_t i = 0; i < count; ++i) {
- if (a[i] != b[i])
- return false;
- }
- return true;
-}
diff --git a/library/cpp/deprecated/autoarray/ya.make b/library/cpp/deprecated/autoarray/ya.make
deleted file mode 100644
index 4b055f8c29..0000000000
--- a/library/cpp/deprecated/autoarray/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-LIBRARY()
-
-SRCS(
- autoarray.cpp
-)
-
-END()
diff --git a/library/cpp/deprecated/fgood/README.md b/library/cpp/deprecated/fgood/README.md
deleted file mode 100644
index 4f66289657..0000000000
--- a/library/cpp/deprecated/fgood/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-Some ancient wrappers on top of FILE*, and some string manupulation functions.
-
-Alternatives are as follows.
-
-For TFILEPtr. Use TIFStream or TOFStream if you need IO. For some rare use cases a TFileMap might also do.
-
-For fput/fget/getline. Use streams API.
-
-For struct ffb and struct prnstr. Just don't use them. Even if you can figure out what they do.
-
-For sf family of functions and TLineSplitter. Just use Split* from util/string/split.h
-
-For TSFReader. Use TMapTsvFile.
-
-For read_or_die family of functions. Use streams API.
diff --git a/library/cpp/deprecated/fgood/ffb.cpp b/library/cpp/deprecated/fgood/ffb.cpp
deleted file mode 100644
index aa9da861a6..0000000000
--- a/library/cpp/deprecated/fgood/ffb.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-#include "ffb.h"
-
-#include <util/string/util.h> // str_spn
-#include <util/system/compat.h>
-#include <util/generic/yexception.h>
-
-#include <cstdio>
-#include <algorithm>
-
-#include <ctype.h>
-
-#ifdef _win_
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-
-ffb::ffb(FILE* file)
- : TFILEPtr(file)
-{
- if (file && !isatty(fileno(file)) && BUFSIZ < 512 * 1024)
- setvbuf(file, nullptr, _IOFBF, 512 * 1024);
-}
-
-void ffb::operator=(FILE* f) {
- TFILEPtr::operator=(f);
- if (f && !isatty(fileno(f)) && BUFSIZ < 512 * 1024)
- setvbuf(f, nullptr, _IOFBF, 512 * 1024);
-}
-
-void ffb::open(const char* name, const char* mode) {
- TFILEPtr::open(name, mode);
- if (!isatty(fileno(*this)) && BUFSIZ < 512 * 1024)
- setvbuf(*this, nullptr, _IOFBF, 512 * 1024);
-}
-
-int sf(char** fb, char* buf) { //don't want to call sf(fb, buf, 32)
- if (!(*buf && *buf != 10)) {
- *fb = nullptr;
- return 0;
- }
- int n = 1;
- fb[0] = buf;
- while (*buf && *buf != 10 && n < 31) {
- if (*buf == '\t') {
- *buf++ = 0;
- fb[n++] = buf;
- continue;
- }
- buf++;
- }
- if (*buf == 10 && buf[-1] == 13)
- buf[-1] = 0;
- *buf = 0;
- fb[n] = nullptr;
- return n;
-}
-
-int sf(char** fb, char* buf, size_t fb_sz) {
- if (!(*buf && *buf != 10)) {
- *fb = nullptr;
- return 0;
- }
- fb_sz--;
- int n = 1;
- fb[0] = buf;
- while (*buf && *buf != 10 && n < (int)fb_sz) {
- if (*buf == '\t') {
- *buf++ = 0;
- fb[n++] = buf;
- continue;
- }
- buf++;
- }
- if (*buf == 10 && buf[-1] == 13)
- buf[-1] = 0;
- *buf = 0;
- fb[n] = nullptr;
- return n;
-}
-
-inline int sf_blank(char** fb, char* buf, size_t fb_sz) {
- while (isspace((ui8)*buf))
- buf++;
- if (!*buf) {
- *fb = nullptr;
- return 0;
- }
- fb_sz--;
- int n = 1;
- fb[0] = buf;
- while (*buf && *buf != 10 && n < (int)fb_sz) {
- if (isspace((ui8)*buf)) {
- *buf++ = 0;
- while (isspace((ui8)*buf))
- buf++;
- if (*buf)
- fb[n++] = buf;
- continue;
- }
- buf++;
- }
- if (*buf == 10 && buf[-1] == 13)
- buf[-1] = 0;
- *buf = 0;
- fb[n] = nullptr;
- return n;
-}
-
-int sf(char fs, char** fb, char* buf, size_t fb_sz) {
- if (fs == ' ')
- return sf_blank(fb, buf, fb_sz);
- while (*buf == fs)
- buf++;
- if (!(*buf && *buf != 10)) {
- *fb = nullptr;
- return 0;
- }
- fb_sz--;
- int n = 1;
- fb[0] = buf;
- while (*buf && *buf != 10 && n < (int)fb_sz) {
- if (*buf == fs) {
- *buf++ = 0;
- while (*buf == fs)
- buf++;
- fb[n++] = buf;
- continue;
- }
- buf++;
- }
- if (*buf == 10 && buf[-1] == 13)
- buf[-1] = 0;
- *buf = 0;
- fb[n] = nullptr;
- return n;
-}
-
-int sf(const char* fs, char** fb, char* buf, size_t fb_sz) {
- if (!(*buf && *buf != 10)) {
- *fb = nullptr;
- return 0;
- }
- int fs_len = strlen(fs);
- fb_sz--;
- int n = 1;
- fb[0] = buf;
- while (*buf && *buf != 10 && n < (int)fb_sz) {
- if (*buf == *fs && !strncmp(buf + 1, fs + 1, fs_len - 1)) {
- *buf = 0;
- buf += fs_len;
- fb[n++] = buf;
- continue;
- }
- buf++;
- }
- if (*buf == 10 && buf[-1] == 13)
- buf[-1] = 0;
- *buf = 0;
- fb[n] = nullptr;
- return n;
-}
-
-inline bool is_end(const char* p) {
- return !p || !p[0];
-}
-
-int sf(const char* seps, char* buf, char** fb, size_t fb_sz) {
- if (fb_sz < 1 || is_end(buf)) {
- *fb = nullptr;
- return 0;
- }
- str_spn sseps(seps);
- fb[0] = nullptr;
- int n = 0;
- // skip leading delimeters
- buf = sseps.cbrk(buf);
- if (is_end(buf))
- return 0;
- // store fields
- while (n < (int)fb_sz) {
- fb[n++] = buf;
- // find delimeters
- buf = sseps.brk(buf + 1);
- if (is_end(buf))
- break;
- *buf = 0;
- // skip delimiters
- buf = sseps.cbrk(buf + 1);
- if (is_end(buf))
- break;
- }
- fb[n] = nullptr;
- return n;
-}
-
-void TLineSplitter::operator()(char* p, TVector<char*>& fields) const {
- if (!p || !*p)
- return;
- char* q = p;
- while (1) {
- p = Sep.brk(p);
- if (q && (p - q || !SkipEmpty()))
- fields.push_back(q);
- q = nullptr;
- if (!*p)
- break;
- if (SepStrLen == 1 || (SepStrLen > 1 && !strncmp(p + 1, SepStr + 1, SepStrLen - 1))) {
- *p = 0;
- p += SepStrLen;
- q = p;
- } else
- p++;
- }
-}
-
-void TLineSplitter::operator()(const char* p, TVector<std::pair<const char*, size_t>>& fields) const {
- if (!p || !*p)
- return;
- const char* q = p;
- while (1) {
- p = Sep.brk(p);
- if (q && (p - q || !SkipEmpty()))
- fields.push_back(std::make_pair(q, p - q));
- q = nullptr;
- if (!*p)
- break;
- if (SepStrLen == 1 || (SepStrLen > 1 && !strncmp(p + 1, SepStr + 1, SepStrLen - 1))) {
- p += SepStrLen;
- q = p;
- } else
- p++;
- }
-}
-
-TSFReader::TSFReader(const char* fname, char sep, i32 nfrq) // if sep == ' ' isspace will be imitated (for compat)
- : Split(str_spn(sep == ' ' ? "\t\n\v\f\r " : TString(1, sep).data()), sep == ' ')
- , OpenPipe(false)
-{
- Open(fname, nfrq);
-}
-
-TSFReader::TSFReader(const char* fname, const char* sep, i32 nfrq)
- : Split(sep, false)
- , OpenPipe(false)
-{
- Open(fname, nfrq);
-}
-
-TSFReader::TSFReader(const char* fname, const TLineSplitter& spl, i32 nfrq)
- : Split(spl)
- , OpenPipe(false)
-{
- Open(fname, nfrq);
-}
-
-void TSFReader::Open(const char* fname, i32 nfrq, size_t vbuf_size) {
- FieldsRequired = nfrq;
- NF = NR = 0;
-
- if (IsOpen())
- File.close();
-
- if (!fname)
- return;
-
- if (!strcmp(fname, "/dev/stdin")) {
- File.assign(stdin, "/dev/stdin");
- } else {
- if (OpenPipe)
- File.popen(fname, "r");
- else
- File.open(fname, "r");
- }
- OpenPipe = false;
- if (!isatty(fileno(File)))
- setvbuf(File, nullptr, _IOFBF, vbuf_size);
-}
-
-void TSFReader::Popen(const char* pname, i32 nfrq, size_t vbuf_size) {
- OpenPipe = true;
- Open(pname, nfrq, vbuf_size);
-}
-
-bool TSFReader::NextLine(segmented_string_pool* pool) {
- size_t line_len = 0;
-
-#ifdef __FreeBSD__
- char* ptr = fgetln(File, &line_len);
- if (!ptr)
- return false;
- if (!line_len || ptr[line_len - 1] != '\n') { // last line w/o newline
- Buf.AssignNoAlias(ptr, line_len);
- ptr = Buf.begin();
- } else {
- // can safely replace newline with \0
- ptr[line_len - 1] = 0;
- --line_len;
- }
-#else
- if (!getline(File, Buf))
- return false;
- char* ptr = Buf.begin();
- line_len = Buf.size();
-#endif
- if (line_len && ptr[line_len - 1] == '\r')
- ptr[line_len - 1] = 0;
-
- if (pool) {
- char* nptr = pool->append(ptr);
- Y_ASSERT(!strcmp(ptr, nptr));
- ptr = nptr;
- }
-
- ++NR;
- Fields.clear();
- Split(ptr, Fields);
- NF = Fields.size();
-
- if (FieldsRequired != -1 && FieldsRequired != (int)NF)
- ythrow yexception() << File.name() << " line " << NR << ": " << NF << " fields, expected " << FieldsRequired;
-
- return true;
-}
-
-int prnstr::f(const char* c, ...) {
- va_list params;
- int n = asize - pos, k;
- va_start(params, c);
- while ((k = vsnprintf(buf + pos, n, c, params)) >= n) {
- n += asize, asize *= 2;
- while (k + pos >= n)
- n += asize, asize *= 2;
- char* t = new char[asize];
- memcpy(t, buf, pos);
- delete[] buf;
- buf = t;
- va_end(params);
- va_start(params, c);
- }
- pos += k;
- va_end(params);
- return k;
-}
-int prnstr::s(const char* c, size_t k) {
- if (!c)
- return 0;
- size_t n = asize - pos;
- if (k >= n) {
- n += asize, asize *= 2;
- while (k + pos >= n)
- n += asize, asize *= 2;
- char* t = new char[asize];
- memcpy(t, buf, pos);
- delete[] buf;
- buf = t;
- }
- memcpy(buf + pos, c, k);
- pos += k;
- buf[pos] = 0;
- return k;
-}
-void prnstr::clear() {
- pos = 0;
- if (asize > 32768) {
- asize = 32768;
- delete[] buf;
- buf = new char[asize];
- }
-}
-
-void prnstr::swap(prnstr& w) {
- std::swap(buf, w.buf);
- std::swap(pos, w.pos);
- std::swap(asize, w.asize);
-}
-
-FILE* read_or_die(const char* fname) {
- FILE* f = fopen(fname, "rb");
- if (!f)
- err(1, "%s", fname);
- return f;
-}
-FILE* write_or_die(const char* fname) {
- FILE* f = fopen(fname, "wb");
- if (!f)
- err(1, "%s", fname);
- return f;
-}
-FILE* fopen_or_die(const char* fname, const char* mode) {
- FILE* f = fopen(fname, mode);
- if (!f)
- err(1, "%s (mode '%s')", fname, mode);
- return f;
-}
-
-FILE* fopen_chk(const char* fname, const char* mode) {
- FILE* f = fopen(fname, mode);
- if (!f)
- ythrow yexception() << fname << " (mode '" << mode << "'): " << LastSystemErrorText();
- return f;
-}
-
-void fclose_chk(FILE* f, const char* fname) {
- if (fclose(f))
- ythrow yexception() << "file " << fname << ": " << LastSystemErrorText();
-}
diff --git a/library/cpp/deprecated/fgood/ffb.h b/library/cpp/deprecated/fgood/ffb.h
deleted file mode 100644
index ca229eb65a..0000000000
--- a/library/cpp/deprecated/fgood/ffb.h
+++ /dev/null
@@ -1,264 +0,0 @@
-#pragma once
-
-#include "fgood.h"
-
-#include <util/string/util.h> // str_spn
-#include <util/string/split.h> // str_spn
-#include <util/memory/segmented_string_pool.h>
-#include <util/generic/string.h>
-#include <util/generic/vector.h>
-#include <util/generic/noncopyable.h>
-
-#include <utility>
-
-#include <cstdarg>
-#include <cstring>
-
-struct ffb: public TFILEPtr {
- ffb() {
- }
- ffb(FILE* file);
- ffb(const char* name, const char* mode) {
- open(name, mode);
- }
- void operator=(FILE* f); // take ownership
- void open(const char* name, const char* mode);
- int f(const char* c, ...) {
- va_list args;
- va_start(args, c);
- return vfprintf(*this, c, args);
- }
- void s(const char* c) {
- fsput(c, strlen(c));
- }
- void b(const void* cc, int n) {
- fsput((const char*)cc, n);
- }
- void B(const void* cc, int N) {
- fsput((const char*)cc, N);
- }
- void c(char c) {
- fputc(c);
- }
- void cbe(wchar16 c) { // big endian utf-16
- fputc(char(c >> 8)); //Hi8
- fputc(char(c & 255)); //Lo8
- }
- void sbe(const wchar16* c) {
- for (; *c; c++)
- cbe(*c);
- }
- void fclose() {
- close();
- }
-};
-
-// split fields of tab-delimited line of text
-// here and below fb actual size must be fb_sz + 1 to allow fb[fb_sz] be zero
-int sf(char** fb, char* buf, size_t fb_sz);
-int sf(char** fb, char* buf /* fb_sz == 32 */);
-
-// split fields of char-delimited line of text
-// Achtung: delim = ' ' imitates awk: initial separators are skipped,
-// repeated seps treated as one, all chars less than ' ' treated as separators.
-int sf(char fs, char** fb, char* buf, size_t fb_sz = 32);
-
-// split fields of string-delimited line of text (fs is NOT a regexp)
-// (usually fs is "@@")
-int sf(const char* fs, char** fb, char* buf, size_t fb_sz = 32);
-
-// split fields of char-delimited line of text, set of char-separators is given
-// Achtung: repeated seps treated as one, initial seps are skipped
-// newlines are NOT ignored.
-int sf(const char* seps, char* buf, char** fb, size_t fb_sz = 32);
-
-inline char* chomp(char* buf) {
- char* c = buf + strlen(buf);
- if (c > buf && c[-1] == '\n') {
- *--c = 0;
-#ifdef _win32_
- if (c > buf && c[-1] == '\r')
- *--c = 0;
-#endif
- }
- return buf;
-}
-
-inline char* chomp_cr(char* buf) {
- char* c = buf + strlen(buf);
- if (c > buf && c[-1] == '\n')
- *--c = 0;
- if (c > buf && c[-1] == '\r')
- *--c = 0;
- return buf;
-}
-
-class TLineSplitter {
-protected:
- enum { // Default: Split string by SepStr
- SplitByAnySep = 1, // Split string by Sep
- NoEmptyFields = 2 // Skip all empty fields between separators
- };
-
-private:
- ui32 Flags;
- const str_spn Sep; // collection of separators
- const char* SepStr; // pointer exact string to separate by
- size_t SepStrLen; // length of separator string
-
-public:
- TLineSplitter(const char* sep, bool noEmpty)
- : Flags(noEmpty ? NoEmptyFields : 0)
- , Sep(TString(sep, 1).data())
- , SepStr(sep)
- , SepStrLen(strlen(sep))
- {
- }
- TLineSplitter(const str_spn& sep, bool noEmpty = false)
- : Flags(SplitByAnySep | (noEmpty ? NoEmptyFields : 0))
- , Sep(sep)
- , SepStr(nullptr)
- , SepStrLen(1)
- {
- }
- bool AnySep() const {
- return Flags & SplitByAnySep;
- }
- bool SkipEmpty() const {
- return Flags & NoEmptyFields;
- }
- /// Separates string onto tokens
- /// Expecting a zero-terminated string
- /// By default returns empty fields between sequential separators
- void operator()(char* p, TVector<char*>& fields) const;
- /// Same, but for const string - fills vector of pairs (pointer, length)
- void operator()(const char* p, TVector<std::pair<const char*, size_t>>& fields) const;
-};
-
-/**
- * Use library/cpp/map_text_file/map_tsv_file.h instead.
- */
-class TSFReader {
- TString Buf; // buffer used for non-'\n'-terminated string and for non-freebsd work
- TLineSplitter Split;
- TVector<char*> Fields;
- size_t NF; // Fields.size()
- size_t NR;
-
- TFILEPtr File;
-
- bool OpenPipe; // internal flag that turns open() to popen()
-
- i32 FieldsRequired; // if != -1, != nf, terminate program
-
-public:
- // char separator
- // Achtung: delim = ' ' imitates awk: initial separators are skipped,
- // all chars less than ' ' treated as separators.
- TSFReader(const char* fname = nullptr, char sep = '\t', i32 nf_reqired = -1);
- // exact string separator
- TSFReader(const char* fname, const char* sep, i32 nf_reqired = -1);
- // fully customizable
- TSFReader(const char* fname, const TLineSplitter& spl, i32 nf_reqired = -1);
-
- void Open(const char* fname, i32 nf_reqired = -1, size_t vbufsize = 1u << 21); // use "/dev/stdin" for stdin
- void Popen(const char* pname, i32 nf_reqired = -1, size_t vbufsize = 1u << 21);
-
- bool NextLine(segmented_string_pool* pool = nullptr);
-
- bool IsOpen() const {
- return (FILE*)File != nullptr;
- }
- bool IsEof() const {
- return feof(File);
- }
- void Close() {
- File.close();
- }
- void Rewind() {
- File.seek(0, SEEK_SET);
- }
- void Seek(i64 offset, int mode = SEEK_SET) {
- File.seek(offset, mode);
- }
- i64 Tell() const {
- return ftell(File);
- }
- char*& operator[](size_t ind) {
- //if (ind >= NF)
- // throw yexception("Can't return reference to unexisting field %" PRISZT, ind);
- return Fields[ind];
- }
- const char* operator[](size_t ind) const {
- if (ind >= NF)
- return nullptr;
- return Fields[ind];
- }
- operator int() const { // note: empty input line makes 0 fields
- return (int)NF;
- }
- const char* Name() const {
- return File.name().data();
- }
- size_t Line() const {
- return NR;
- }
- const TVector<char*>& GetFields() const {
- return Fields;
- }
-};
-
-struct prnstr {
- char* buf;
- int pos;
- int asize;
- prnstr()
- : pos(0)
- {
- asize = 32;
- buf = new char[asize];
- }
- explicit prnstr(int asz)
- : pos(0)
- {
- asize = asz;
- buf = new char[asize];
- }
- int f(const char* c, ...);
- int s(const char* c1, const char* c2);
- int s(const char* c1, const char* c2, const char* c3);
- int s(const char* c, size_t len);
- //int s(const char *c);
- int s(const char* c) {
- return c ? s(c, strlen(c)) : 0;
- }
- int s(const TString& c);
- int s_htmesc(const char* c, bool enc_utf = false);
- int s_htmesc_w(const char* c);
- int c(char c);
- int cu(wchar32 c); //for utf-8
- void restart() {
- *buf = 0;
- pos = 0;
- }
- const char* operator~() const {
- return buf;
- }
- int operator+() const {
- return pos;
- }
- ~prnstr() {
- delete[] buf;
- }
- void clear();
- void swap(prnstr& w);
-};
-
-// functions that terminate program upon failure
-FILE* read_or_die(const char* fname);
-FILE* write_or_die(const char* fname);
-FILE* fopen_or_die(const char* fname, const char* mode);
-
-// functions that throw upon failure
-FILE* fopen_chk(const char* fname, const char* mode);
-void fclose_chk(FILE* f, const char* fname_dbg);
diff --git a/library/cpp/deprecated/fgood/fgood.cpp b/library/cpp/deprecated/fgood/fgood.cpp
deleted file mode 100644
index 5d4725bfae..0000000000
--- a/library/cpp/deprecated/fgood/fgood.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "fgood.h"
-
-#include <util/generic/cast.h>
-#include <util/string/cast.h>
-#include <util/system/fstat.h>
-
-#ifdef _win32_
-#include <io.h>
-#endif
-
-i64 TFILEPtr::length() const {
-#ifdef _win32_
- FHANDLE fd = (FHANDLE)_get_osfhandle(fileno(m_file));
-#else
- FHANDLE fd = fileno(m_file);
-#endif
- i64 rv = GetFileLength(fd);
- if (rv < 0)
- ythrow yexception() << "TFILEPtr::length() " << Name.data() << ": " << LastSystemErrorText();
- return rv;
-}
-
-FILE* OpenFILEOrFail(const TString& name, const char* mode) {
- FILE* res = ::fopen(name.data(), mode);
- if (!res) {
- ythrow yexception() << "can't open \'" << name << "\' with mode \'" << mode << "\': " << LastSystemErrorText();
- }
- return res;
-}
-
-void TFILECloser::Destroy(FILE* file) {
- ::fclose(file);
-}
-
-#ifdef _freebsd_ // fgetln
-#define getline getline_alt_4test
-#endif // _freebsd_
-
-bool getline(TFILEPtr& f, TString& s) {
- char buf[4096];
- char* buf_ptr;
- if (s.capacity() > sizeof(buf)) {
- s.resize(s.capacity());
- if ((buf_ptr = fgets(s.begin(), IntegerCast<int>(s.capacity()), f)) == nullptr)
- return false;
- } else {
- if ((buf_ptr = fgets(buf, sizeof(buf), f)) == nullptr)
- return false;
- }
- size_t buf_len = strlen(buf_ptr);
- bool line_complete = buf_len && buf_ptr[buf_len - 1] == '\n';
- if (line_complete)
- buf_len--;
- if (buf_ptr == s.begin())
- s.resize(buf_len);
- else
- s.AssignNoAlias(buf, buf_len);
- if (line_complete)
- return true;
- while (fgets(buf, sizeof(buf), f)) {
- size_t buf_len2 = strlen(buf);
- if (buf_len2 && buf[buf_len2 - 1] == '\n') {
- buf[buf_len2 - 1] = 0;
- s.append(buf, buf_len2 - 1);
- return true;
- }
- s.append(buf, buf_len2);
- }
- return true;
-}
diff --git a/library/cpp/deprecated/fgood/fgood.h b/library/cpp/deprecated/fgood/fgood.h
deleted file mode 100644
index 0aaf910c0f..0000000000
--- a/library/cpp/deprecated/fgood/fgood.h
+++ /dev/null
@@ -1,328 +0,0 @@
-#pragma once
-
-#include <util/system/yassert.h>
-#include <util/system/defaults.h>
-#include <util/generic/string.h>
-#include <util/generic/yexception.h>
-#include <util/generic/ptr.h>
-
-#include "fput.h"
-
-#include <cstdio>
-
-#include <fcntl.h>
-
-#ifdef _unix_
-extern "C" int __ungetc(int, FILE*);
-#endif
-
-#if (!defined(__FreeBSD__) && !defined(__linux__) && !defined(_darwin_) && !defined(_cygwin_)) || defined(_bionic_)
-#define feof_unlocked(_stream) feof(_stream)
-#define ferror_unlocked(_stream) ferror(_stream)
-#endif
-
-#ifndef _unix_
-#if defined(_MSC_VER) && (_MSC_VER < 1900)
-#define getc_unlocked(_stream) (--(_stream)->_cnt >= 0 ? 0xff & *(_stream)->_ptr++ : _filbuf(_stream))
-#define putc_unlocked(_c, _stream) (--(_stream)->_cnt >= 0 ? 0xff & (*(_stream)->_ptr++ = (char)(_c)) : _flsbuf((_c), (_stream)))
-#else
-#define getc_unlocked(_stream) getc(_stream)
-#define putc_unlocked(_c, _stream) putc(_c, _stream)
-#endif
-#endif
-
-inline bool fgood(FILE* f) {
- return !feof_unlocked(f) && !ferror_unlocked(f);
-}
-
-#ifdef _win32_
-// These functions will work only with static MSVC runtime linkage. For dynamic linkage,
-// fseeki64.c and ftelli64.c from CRT sources should be included in project
-extern "C" int __cdecl _fseeki64(FILE*, __int64, int);
-extern "C" __int64 __cdecl _ftelli64(FILE*);
-
-inline i64 ftello(FILE* stream) {
- return _ftelli64(stream);
-}
-
-inline int fseeko(FILE* stream, i64 offset, int origin) {
- return _fseeki64(stream, offset, origin);
-}
-#endif
-
-class TFILEPtr {
-private:
- enum { SHOULD_CLOSE = 1,
- IS_PIPE = 2 };
- FILE* m_file;
- int m_Flags;
- TString Name;
-
-public:
- TFILEPtr() noexcept {
- m_file = nullptr;
- m_Flags = 0;
- }
- TFILEPtr(const TString& name, const char* mode) {
- m_file = nullptr;
- m_Flags = 0;
- open(name, mode);
- }
- TFILEPtr(const TFILEPtr& src) noexcept {
- m_file = src.m_file;
- m_Flags = 0;
- }
- TFILEPtr& operator=(const TFILEPtr& src) {
- if (src.m_file != m_file) {
- close();
- m_file = src.m_file;
- m_Flags = 0;
- }
- return *this;
- }
- explicit TFILEPtr(FILE* f) noexcept { // take ownership
- m_file = f;
- m_Flags = SHOULD_CLOSE;
- }
- TFILEPtr& operator=(FILE* f) { // take ownership
- if (f != m_file) {
- close();
- m_file = f;
- m_Flags = SHOULD_CLOSE;
- }
- return *this;
- }
- const TString& name() const {
- return Name;
- }
- operator FILE*() const noexcept {
- return m_file;
- }
- FILE* operator->() const noexcept {
- return m_file;
- }
- bool operator!() const noexcept {
- return m_file == nullptr;
- }
- bool operator!=(FILE* f) const noexcept {
- return m_file != f;
- }
- bool operator==(FILE* f) const noexcept {
- return m_file == f;
- }
- ~TFILEPtr() {
- close();
- }
- void Y_PRINTF_FORMAT(2, 3) check(const char* message, ...) const {
- if (Y_UNLIKELY(!fgood(m_file))) {
- va_list args;
- va_start(args, message);
- char buf[512];
- vsnprintf(buf, 512, message, args);
- // XXX: errno is undefined here
- ythrow yexception() << buf << ": " << LastSystemErrorText() << ", " << Name.data() << " at offset " << (i64)ftell();
- }
- }
- TFILEPtr& assign(FILE* f, const char* name = nullptr) { // take ownership and have a name
- *this = f;
- if (name)
- Name = name;
- return *this;
- }
- void open(const TString& name, const char* mode) {
- Y_ASSERT(!name.empty());
- Y_ASSERT(m_file == nullptr);
- m_file = ::fopen(name.data(), mode);
- if (!m_file)
- ythrow yexception() << "can't open \'" << name << "\' with mode \'" << mode << "\': " << LastSystemErrorText();
- m_Flags = SHOULD_CLOSE;
- Name = name;
- }
- void popen(const TString& command, const char* mode) {
- Y_ASSERT(!command.empty());
- Y_ASSERT(m_file == nullptr);
- m_file = ::popen(command.data(), mode);
- if (!m_file)
- ythrow yexception() << "can't execute \'" << command << "\' with mode \'" << mode << "\': " << LastSystemErrorText();
- m_Flags = IS_PIPE | SHOULD_CLOSE;
- Name = command;
- }
- void close() {
- if (m_file != nullptr && (m_Flags & SHOULD_CLOSE)) {
- if ((m_Flags & IS_PIPE) ? ::pclose(m_file) : ::fclose(m_file)) {
- m_file = nullptr;
- m_Flags = 0;
- if (!UncaughtException())
- ythrow yexception() << "can't close file " << Name.data() << ": " << LastSystemErrorText();
- }
- }
- m_file = nullptr;
- m_Flags = 0;
- Name.clear();
- }
- size_t write(const void* buffer, size_t size, size_t count) const {
- Y_ASSERT(m_file != nullptr);
- size_t r = ::fwrite(buffer, size, count, m_file);
- check("can't write %lu bytes", (unsigned long)size * count);
- return r;
- }
- size_t read(void* buffer, size_t size, size_t count) const {
- Y_ASSERT(m_file != nullptr);
- size_t r = ::fread(buffer, size, count, m_file);
- if (ferror_unlocked(m_file))
- ythrow yexception() << "can't read " << (unsigned long)size * count << " bytes: " << LastSystemErrorText() << ", " << Name.data() << " at offset " << (i64)ftell();
- return r;
- }
- char* fgets(char* buffer, int size) const {
- Y_ASSERT(m_file != nullptr);
- char* r = ::fgets(buffer, size, m_file);
- if (ferror_unlocked(m_file))
- ythrow yexception() << "can't read string of maximum size " << size << ": " << LastSystemErrorText() << ", " << Name.data() << " at offset " << (i64)ftell();
- return r;
- }
- void Y_PRINTF_FORMAT(2, 3) fprintf(const char* format, ...) {
- Y_ASSERT(m_file != nullptr);
- va_list args;
- va_start(args, format);
- vfprintf(m_file, format, args);
- check("can't write");
- }
- void seek(i64 offset, int origin) const {
- Y_ASSERT(m_file != nullptr);
-#if defined(_unix_) || defined(_win32_)
- if (fseeko(m_file, offset, origin) != 0)
-#else
- Y_ASSERT(offset == (i64)(i32)offset);
- if (::fseek(m_file, (long)offset, origin) != 0)
-#endif
- ythrow yexception() << "can't seek " << Name.data() << " by " << offset << ": " << LastSystemErrorText();
- }
- i64 length() const; // uses various system headers -> in fileptr.cpp
-
- void setDirect() const {
-#if !defined(_win_) && !defined(_darwin_)
- if (!m_file)
- ythrow yexception() << "file not open";
- if (fcntl(fileno(m_file), F_SETFL, O_DIRECT) == -1)
- ythrow yexception() << "Cannot set O_DIRECT flag";
-#endif
- }
-
- // for convenience
-
- i64 ftell() const noexcept {
-#if defined(_unix_) || defined(_win32_)
- return ftello(m_file);
-#else
- return ftell(m_file);
-#endif
- }
- bool eof() const noexcept {
- Y_ASSERT(m_file != nullptr);
- return feof_unlocked(m_file) != 0;
- }
- int fputc(int c) {
- Y_ASSERT(m_file != nullptr);
- return putc_unlocked(c, m_file);
- }
- size_t fputs(const char* buffer) const {
- return write(buffer, strlen(buffer), 1);
- }
- int fgetc() {
- Y_ASSERT(m_file != nullptr);
- return getc_unlocked(m_file);
- }
- int ungetc(int c) {
- Y_ASSERT(m_file != nullptr);
- return ::ungetc(c, m_file);
- }
- template <class T>
- size_t fput(const T& a) {
- Y_ASSERT(m_file != nullptr);
- return ::fput(m_file, a);
- }
- template <class T>
- size_t fget(T& a) {
- Y_ASSERT(m_file != nullptr);
- return ::fget(m_file, a);
- }
- size_t fsput(const char* s, size_t l) {
- Y_ASSERT(m_file != nullptr);
- return ::fsput(m_file, s, l);
- }
- size_t fsget(char* s, size_t l) {
- Y_ASSERT(m_file != nullptr);
- return ::fsget(m_file, s, l);
- }
-
- void fflush() {
- ::fflush(m_file);
- }
-
- /* This block contains some TFile/TStream - compatible names */
- size_t Read(void* bufferIn, size_t numBytes) {
- size_t r = fsget((char*)bufferIn, numBytes);
- if (Y_UNLIKELY(ferror_unlocked(m_file)))
- ythrow yexception() << "can't read " << numBytes << " bytes: " << LastSystemErrorText() << ", " << Name << " at offset " << (i64)ftell();
- return r;
- }
- void Write(const void* buffer, size_t numBytes) {
- write(buffer, 1, numBytes);
- }
- i64 Seek(i64 offset, int origin /*SeekDir*/) {
- seek(offset, origin);
- return ftell();
- }
- i64 GetPosition() const noexcept {
- return ftell();
- }
- i64 GetLength() const noexcept {
- return length();
- }
- bool ReadLine(TString& st);
-
- /* Similar to TAutoPtr::Release - return pointer and forget about it. */
- FILE* Release() noexcept {
- FILE* result = m_file;
- m_file = nullptr;
- m_Flags = 0;
- Name.clear();
- return result;
- }
-};
-
-inline void fclose(TFILEPtr& F) {
- F.close();
-}
-
-inline void fseek(const TFILEPtr& F, i64 offset, int whence) {
- F.seek(offset, whence);
-}
-
-#ifdef _freebsd_ // fgetln
-inline bool getline(TFILEPtr& f, TString& s) {
- size_t len;
- char* buf = fgetln(f, &len);
- if (!buf)
- return false;
- if (len && buf[len - 1] == '\n')
- len--;
- s.AssignNoAlias(buf, len);
- return true;
-}
-#else
-bool getline(TFILEPtr& f, TString& s);
-#endif //_freebsd_
-
-inline bool TFILEPtr::ReadLine(TString& st) {
- return getline(*this, st);
-}
-
-FILE* OpenFILEOrFail(const TString& name, const char* mode);
-
-//Should be used with THolder
-struct TFILECloser {
- static void Destroy(FILE* file);
-};
-
-using TFILEHolder = THolder<FILE, TFILECloser>;
diff --git a/library/cpp/deprecated/fgood/fput.h b/library/cpp/deprecated/fgood/fput.h
deleted file mode 100644
index 690b06332d..0000000000
--- a/library/cpp/deprecated/fgood/fput.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-
-#include <util/system/defaults.h>
-#include <util/system/valgrind.h>
-
-#include <cstdio>
-
-#ifdef __FreeBSD__
-#include <cstring>
-
-template <class T>
-Y_FORCE_INLINE size_t fput(FILE* F, const T& a) {
- if (Y_LIKELY(F->_w >= int(sizeof(a)))) {
- memcpy(F->_p, &a, sizeof(a));
- F->_p += sizeof(a);
- F->_w -= sizeof(a);
- return 1;
- } else {
- return fwrite(&a, sizeof(a), 1, F);
- }
-}
-
-template <class T>
-Y_FORCE_INLINE size_t fget(FILE* F, T& a) {
- if (Y_LIKELY(F->_r >= int(sizeof(a)))) {
- memcpy(&a, F->_p, sizeof(a));
- F->_p += sizeof(a);
- F->_r -= sizeof(a);
- return 1;
- } else {
- return fread(&a, sizeof(a), 1, F);
- }
-}
-
-inline size_t fsput(FILE* F, const char* s, size_t l) {
- VALGRIND_CHECK_READABLE(s, l);
-
- if ((size_t)F->_w >= l) {
- memcpy(F->_p, s, l);
- F->_p += l;
- F->_w -= l;
- return l;
- } else {
- return fwrite(s, 1, l, F);
- }
-}
-
-inline size_t fsget(FILE* F, char* s, size_t l) {
- if ((size_t)F->_r >= l) {
- memcpy(s, F->_p, l);
- F->_p += l;
- F->_r -= l;
- return l;
- } else {
- return fread(s, 1, l, F);
- }
-}
-#else
-template <class T>
-Y_FORCE_INLINE size_t fput(FILE* F, const T& a) {
- return fwrite(&a, sizeof(a), 1, F);
-}
-
-template <class T>
-Y_FORCE_INLINE size_t fget(FILE* F, T& a) {
- return fread(&a, sizeof(a), 1, F);
-}
-
-inline size_t fsput(FILE* F, const char* s, size_t l) {
-#ifdef WITH_VALGRIND
- VALGRIND_CHECK_READABLE(s, l);
-#endif
- return fwrite(s, 1, l, F);
-}
-
-inline size_t fsget(FILE* F, char* s, size_t l) {
- return fread(s, 1, l, F);
-}
-#endif
diff --git a/library/cpp/deprecated/fgood/ya.make b/library/cpp/deprecated/fgood/ya.make
deleted file mode 100644
index 2394f9ad7a..0000000000
--- a/library/cpp/deprecated/fgood/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-LIBRARY()
-
-SRCS(
- ffb.cpp
- fgood.cpp
-)
-
-END()
diff --git a/library/cpp/deprecated/mapped_file/mapped_file.cpp b/library/cpp/deprecated/mapped_file/mapped_file.cpp
deleted file mode 100644
index b0e4511299..0000000000
--- a/library/cpp/deprecated/mapped_file/mapped_file.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "mapped_file.h"
-
-#include <util/generic/yexception.h>
-#include <util/system/defaults.h>
-#include <util/system/hi_lo.h>
-#include <util/system/filemap.h>
-
-TMappedFile::TMappedFile(TFileMap* map, const char* dbgName) {
- Map_ = map;
- i64 len = Map_->Length();
- if (Hi32(len) != 0 && sizeof(size_t) <= sizeof(ui32))
- ythrow yexception() << "File '" << dbgName << "' mapping error: " << len << " too large";
-
- Map_->Map(0, static_cast<size_t>(len));
-}
-
-TMappedFile::TMappedFile(const TFile& file, TFileMap::EOpenMode om, const char* dbgName)
- : Map_(nullptr)
-{
- init(file, om, dbgName);
-}
-
-void TMappedFile::precharge(size_t off, size_t size) const {
- if (!Map_)
- return;
-
- Map_->Precharge(off, size);
-}
-
-void TMappedFile::init(const TString& name) {
- THolder<TFileMap> map(new TFileMap(name));
- TMappedFile newFile(map.Get(), name.data());
- Y_UNUSED(map.Release());
- newFile.swap(*this);
- newFile.term();
-}
-
-void TMappedFile::init(const TString& name, size_t length, TFileMap::EOpenMode om) {
- THolder<TFileMap> map(new TFileMap(name, length, om));
- TMappedFile newFile(map.Get(), name.data());
- Y_UNUSED(map.Release());
- newFile.swap(*this);
- newFile.term();
-}
-
-void TMappedFile::init(const TFile& file, TFileMap::EOpenMode om, const char* dbgName) {
- THolder<TFileMap> map(new TFileMap(file, om));
- TMappedFile newFile(map.Get(), dbgName);
- Y_UNUSED(map.Release());
- newFile.swap(*this);
- newFile.term();
-}
-
-void TMappedFile::init(const TString& name, TFileMap::EOpenMode om) {
- THolder<TFileMap> map(new TFileMap(name, om));
- TMappedFile newFile(map.Get(), name.data());
- Y_UNUSED(map.Release());
- newFile.swap(*this);
- newFile.term();
-}
-
-void TMappedFile::flush() {
- Map_->Flush();
-}
diff --git a/library/cpp/deprecated/mapped_file/ya.make b/library/cpp/deprecated/mapped_file/ya.make
deleted file mode 100644
index 309341f1da..0000000000
--- a/library/cpp/deprecated/mapped_file/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-LIBRARY()
-
-SRCS(
- mapped_file.cpp
-)
-
-END()
diff --git a/library/cpp/eventlog/common.h b/library/cpp/eventlog/common.h
deleted file mode 100644
index 75c512c13e..0000000000
--- a/library/cpp/eventlog/common.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-template <class T>
-class TPacketInputStream {
-public:
- virtual bool Avail() const = 0;
- virtual T operator*() const = 0;
- virtual bool Next() = 0;
- virtual ~TPacketInputStream() = default;
-};
diff --git a/library/cpp/eventlog/evdecoder.cpp b/library/cpp/eventlog/evdecoder.cpp
deleted file mode 100644
index e4413a1b0e..0000000000
--- a/library/cpp/eventlog/evdecoder.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-#include <util/memory/tempbuf.h>
-#include <util/string/cast.h>
-#include <util/stream/output.h>
-
-#include "evdecoder.h"
-#include "logparser.h"
-
-static const char* const UNKNOWN_EVENT_CLASS = "Unknown event class";
-
-static inline void LogError(ui64 frameAddr, const char* msg, bool strict) {
- if (!strict) {
- Cerr << "EventDecoder warning @" << frameAddr << ": " << msg << Endl;
- } else {
- ythrow yexception() << "EventDecoder error @" << frameAddr << ": " << msg;
- }
-}
-
-static inline bool SkipData(IInputStream& s, size_t amount) {
- return (amount == s.Skip(amount));
-}
-
-// There are 2 log fomats: the one, that allows event skip without event decode (it has stored event length)
-// and another, that requires each event decode just to seek over stream. needRead == true means the latter format.
-static inline THolder<TEvent> DoDecodeEvent(IInputStream& s, const TEventFilter* const filter, const bool needRead, IEventFactory* fac) {
- TEventTimestamp ts;
- TEventClass c;
- THolder<TEvent> e;
-
- ::Load(&s, ts);
- ::Load(&s, c);
-
- bool needReturn = false;
-
- if (!filter || filter->EventAllowed(c)) {
- needReturn = true;
- }
-
- if (needRead || needReturn) {
- e.Reset(fac->CreateLogEvent(c));
-
- if (!!e) {
- e->Timestamp = ts;
- e->Load(s);
- } else if (needReturn) {
- e.Reset(new TUnknownEvent(ts, c));
- }
-
- if (!needReturn) {
- e.Reset(nullptr);
- }
- }
-
- return e;
-}
-
-THolder<TEvent> DecodeFramed(IInputStream& inp, ui64 frameAddr, const TEventFilter* const filter, IEventFactory* fac, bool strict) {
- ui32 len;
- ::Load(&inp, len);
-
- if (len < sizeof(ui32)) {
- ythrow TEventDecoderError() << "invalid event length";
- }
-
- TLengthLimitedInput s(&inp, len - sizeof(ui32));
-
- try {
- THolder<TEvent> e = DoDecodeEvent(s, filter, false, fac);
- if (!!e) {
- if (!s.Left()) {
- return e;
- } else if (e->Class == 0) {
- if (!SkipData(s, s.Left())) {
- ythrow TEventDecoderError() << "cannot skip bad event";
- }
-
- return e;
- }
-
- LogError(frameAddr, "Event is not fully read", strict);
- }
- } catch (const TLoadEOF&) {
- if (s.Left()) {
- throw;
- }
-
- LogError(frameAddr, "Unexpected event end", strict);
- }
-
- if (!SkipData(s, s.Left())) {
- ythrow TEventDecoderError() << "cannot skip bad event";
- }
-
- return nullptr;
-}
-
-THolder<TEvent> DecodeEvent(IInputStream& s, bool framed, ui64 frameAddr, const TEventFilter* const filter, IEventFactory* fac, bool strict) {
- try {
- if (framed) {
- return DecodeFramed(s, frameAddr, filter, fac, strict);
- } else {
- THolder<TEvent> e = DoDecodeEvent(s, filter, true, fac);
- // e(0) means event, skipped by filter. Not an error.
- if (!!e && !e->Class) {
- ythrow TEventDecoderError() << UNKNOWN_EVENT_CLASS;
- }
-
- return e;
- }
- } catch (const TLoadEOF&) {
- ythrow TEventDecoderError() << "unexpected frame end";
- }
-}
diff --git a/library/cpp/eventlog/evdecoder.h b/library/cpp/eventlog/evdecoder.h
deleted file mode 100644
index eedfc82174..0000000000
--- a/library/cpp/eventlog/evdecoder.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include <util/generic/yexception.h>
-#include <util/generic/ptr.h>
-
-#include "eventlog.h"
-
-class TEvent;
-class IInputStream;
-class TEventFilter;
-
-struct TEventDecoderError: public yexception {
-};
-
-THolder<TEvent> DecodeEvent(IInputStream& s, bool framed, ui64 frameAddr, const TEventFilter* const filter, IEventFactory* fac, bool strict = false);
-bool AcceptableContent(TEventLogFormat);
diff --git a/library/cpp/eventlog/event_field_output.cpp b/library/cpp/eventlog/event_field_output.cpp
deleted file mode 100644
index f9d98dac9d..0000000000
--- a/library/cpp/eventlog/event_field_output.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "event_field_output.h"
-
-#include <util/string/split.h>
-
-namespace {
- TString MakeSeparators(EFieldOutputFlags flags) {
- TString res;
- res.reserve(3);
-
- if (flags & EFieldOutputFlag::EscapeTab) {
- res.append('\t');
- }
- if (flags & EFieldOutputFlag::EscapeNewLine) {
- res.append('\n');
- res.append('\r');
- }
- if (flags & EFieldOutputFlag::EscapeBackSlash) {
- res.append('\\');
- }
-
- return res;
- }
-}
-
-TEventFieldOutput::TEventFieldOutput(IOutputStream& output, EFieldOutputFlags flags)
- : Output(output)
- , Flags(flags)
- , Separators(MakeSeparators(flags))
-{
-}
-
-IOutputStream& TEventFieldOutput::GetOutputStream() {
- return Output;
-}
-
-EFieldOutputFlags TEventFieldOutput::GetFlags() const {
- return Flags;
-}
-
-void TEventFieldOutput::DoWrite(const void* buf, size_t len) {
- if (!Flags) {
- Output.Write(buf, len);
- return;
- }
-
- TStringBuf chunk{static_cast<const char*>(buf), len};
-
- for (const auto part : StringSplitter(chunk).SplitBySet(Separators.data())) {
- TStringBuf token = part.Token();
- TStringBuf delim = part.Delim();
-
- if (!token.empty()) {
- Output.Write(token);
- }
- if ("\n" == delim) {
- Output.Write(TStringBuf("\\n"));
- } else if ("\r" == delim) {
- Output.Write(TStringBuf("\\r"));
- } else if ("\t" == delim) {
- Output.Write(TStringBuf("\\t"));
- } else if ("\\" == delim) {
- Output.Write(TStringBuf("\\\\"));
- } else {
- Y_ASSERT(delim.empty());
- }
- }
-}
-
diff --git a/library/cpp/eventlog/event_field_output.h b/library/cpp/eventlog/event_field_output.h
deleted file mode 100644
index ed9db0ae16..0000000000
--- a/library/cpp/eventlog/event_field_output.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include <util/stream/output.h>
-#include <util/generic/flags.h>
-
-enum class EFieldOutputFlag {
- EscapeTab = 0x1, // escape \t in field value
- EscapeNewLine = 0x2, // escape \n in field value
- EscapeBackSlash = 0x4 // escape \ in field value
-};
-
-Y_DECLARE_FLAGS(EFieldOutputFlags, EFieldOutputFlag);
-Y_DECLARE_OPERATORS_FOR_FLAGS(EFieldOutputFlags);
-
-class TEventFieldOutput: public IOutputStream {
-public:
- TEventFieldOutput(IOutputStream& output, EFieldOutputFlags flags);
-
- IOutputStream& GetOutputStream();
- EFieldOutputFlags GetFlags() const;
-
-protected:
- void DoWrite(const void* buf, size_t len) override;
-
-private:
- IOutputStream& Output;
- EFieldOutputFlags Flags;
- TString Separators;
-};
diff --git a/library/cpp/eventlog/event_field_printer.cpp b/library/cpp/eventlog/event_field_printer.cpp
deleted file mode 100644
index 29c6b4b661..0000000000
--- a/library/cpp/eventlog/event_field_printer.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "event_field_printer.h"
-
-#include <library/cpp/protobuf/json/proto2json.h>
-
-namespace {
-
- const NProtobufJson::TProto2JsonConfig PROTO_2_JSON_CONFIG = NProtobufJson::TProto2JsonConfig()
- .SetMissingRepeatedKeyMode(NProtobufJson::TProto2JsonConfig::MissingKeyDefault)
- .AddStringTransform(MakeIntrusive<NProtobufJson::TBase64EncodeBytesTransform>());
-
-} // namespace
-
-TEventProtobufMessageFieldPrinter::TEventProtobufMessageFieldPrinter(EProtobufMessageFieldPrintMode mode)
- : Mode(mode)
-{}
-
-template <>
-void TEventProtobufMessageFieldPrinter::PrintProtobufMessageFieldToOutput<google::protobuf::Message, false>(const google::protobuf::Message& field, TEventFieldOutput& output) {
- switch (Mode) {
- case EProtobufMessageFieldPrintMode::DEFAULT:
- case EProtobufMessageFieldPrintMode::JSON: {
- // Do not use field.PrintJSON() here: IGNIETFERRO-2002
- NProtobufJson::Proto2Json(field, output, PROTO_2_JSON_CONFIG);
- break;
- }
- }
-}
diff --git a/library/cpp/eventlog/event_field_printer.h b/library/cpp/eventlog/event_field_printer.h
deleted file mode 100644
index 835e8f4a85..0000000000
--- a/library/cpp/eventlog/event_field_printer.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include "event_field_output.h"
-
-#include <google/protobuf/message.h>
-
-// NB: For historical reasons print code for all primitive types/repeated fields/etc generated by https://a.yandex-team.ru/arc/trunk/arcadia/tools/event2cpp
-
-enum class EProtobufMessageFieldPrintMode {
- // Use <TEventProtobufMessageFieldType>::Print method for fields that has it
- // Print json for other fields
- DEFAULT = 0,
-
- JSON = 1,
-};
-
-class TEventProtobufMessageFieldPrinter {
-public:
- explicit TEventProtobufMessageFieldPrinter(EProtobufMessageFieldPrintMode mode);
-
- template <typename TEventProtobufMessageFieldType, bool HasPrintFunction>
- void PrintProtobufMessageFieldToOutput(const TEventProtobufMessageFieldType& field, TEventFieldOutput& output) {
- if constexpr (HasPrintFunction) {
- if (Mode == EProtobufMessageFieldPrintMode::DEFAULT) {
- field.Print(output.GetOutputStream(), output.GetFlags());
- return;
- }
- }
-
- PrintProtobufMessageFieldToOutput<google::protobuf::Message, false>(field, output);
- }
-
- template <>
- void PrintProtobufMessageFieldToOutput<google::protobuf::Message, false>(const google::protobuf::Message& field, TEventFieldOutput& output);
-
-private:
- EProtobufMessageFieldPrintMode Mode;
-};
diff --git a/library/cpp/eventlog/eventlog.cpp b/library/cpp/eventlog/eventlog.cpp
deleted file mode 100644
index 458a632b4a..0000000000
--- a/library/cpp/eventlog/eventlog.cpp
+++ /dev/null
@@ -1,554 +0,0 @@
-#include <util/datetime/base.h>
-#include <util/stream/zlib.h>
-#include <util/stream/length.h>
-#include <util/generic/buffer.h>
-#include <util/generic/yexception.h>
-#include <util/digest/murmur.h>
-#include <util/generic/singleton.h>
-#include <util/generic/function.h>
-#include <util/stream/output.h>
-#include <util/stream/format.h>
-#include <util/stream/null.h>
-
-#include <google/protobuf/messagext.h>
-
-#include "eventlog.h"
-#include "events_extension.h"
-#include "evdecoder.h"
-#include "logparser.h"
-#include <library/cpp/eventlog/proto/internal.pb.h>
-
-#include <library/cpp/json/json_writer.h>
-#include <library/cpp/protobuf/json/proto2json.h>
-
-
-TAtomic eventlogFrameCounter = 0;
-
-namespace {
-
- const NProtobufJson::TProto2JsonConfig PROTO_2_JSON_CONFIG = NProtobufJson::TProto2JsonConfig()
- .SetMissingRepeatedKeyMode(NProtobufJson::TProto2JsonConfig::MissingKeyDefault)
- .AddStringTransform(MakeIntrusive<NProtobufJson::TBase64EncodeBytesTransform>());
-
- ui32 GenerateFrameId() {
- return ui32(AtomicAdd(eventlogFrameCounter, 1));
- }
-
- inline const NProtoBuf::Message* UnknownEventMessage() {
- return Singleton<NEventLogInternal::TUnknownEvent>();
- }
-
-} // namespace
-
-void TEvent::Print(IOutputStream& out, const TOutputOptions& options, const TEventState& eventState) const {
- if (options.OutputFormat == TOutputFormat::TabSeparatedRaw) {
- PrintHeader(out, options, eventState);
- DoPrint(out, {});
- } else if (options.OutputFormat == TOutputFormat::TabSeparated) {
- PrintHeader(out, options, eventState);
- DoPrint(
- out,
- EFieldOutputFlags{} | EFieldOutputFlag::EscapeNewLine | EFieldOutputFlag::EscapeBackSlash);
- } else if (options.OutputFormat == TOutputFormat::Json) {
- NJson::TJsonWriterConfig jsonWriterConfig;
- jsonWriterConfig.FormatOutput = 0;
- NJson::TJsonWriter jsonWriter(&out, jsonWriterConfig);
-
- jsonWriter.OpenMap();
- PrintJsonHeader(jsonWriter);
- DoPrintJson(jsonWriter);
- jsonWriter.CloseMap();
- }
-}
-
-void TEvent::PrintHeader(IOutputStream& out, const TOutputOptions& options, const TEventState& eventState) const {
- if (options.HumanReadable) {
- out << TInstant::MicroSeconds(Timestamp).ToString() << "\t";
- if (Timestamp >= eventState.FrameStartTime)
- out << "+" << HumanReadable(TDuration::MicroSeconds(Timestamp - eventState.FrameStartTime));
- else // a bug somewhere? anyway, let's handle it in a nice fashion
- out << "-" << HumanReadable(TDuration::MicroSeconds(eventState.FrameStartTime - Timestamp));
-
- if (Timestamp >= eventState.PrevEventTime)
- out << " (+" << HumanReadable(TDuration::MicroSeconds(Timestamp - eventState.PrevEventTime)) << ")";
- // else: these events are async and out-of-order, relative time diff makes no sense, skip it
-
- out << "\tF# " << FrameId << '\t';
- } else {
- out << static_cast<TEventTimestamp>(Timestamp);
- out << '\t' << FrameId << '\t';
- }
-}
-
-void TEvent::PrintJsonHeader(NJson::TJsonWriter& jsonWriter) const {
- jsonWriter.Write("Timestamp", Timestamp);
- jsonWriter.Write("FrameId", FrameId);
-}
-
-class TProtobufEvent: public TEvent {
-public:
- TProtobufEvent(TEventTimestamp t, size_t eventId, const NProtoBuf::Message& msg)
- : TEvent(eventId, t)
- , Message_(&msg)
- , EventFactory_(NProtoBuf::TEventFactory::Instance())
- {
- }
-
- TProtobufEvent()
- : TEvent(0, 0)
- , EventFactory_(NProtoBuf::TEventFactory::Instance())
- {
- }
-
- explicit TProtobufEvent(ui32 id, NProtoBuf::TEventFactory* eventFactory = NProtoBuf::TEventFactory::Instance())
- : TEvent(id, 0)
- , EventFactory_(eventFactory)
- {
- InnerMsg_.Reset(EventFactory_->CreateEvent(Class));
- Message_ = InnerMsg_.Get();
- }
-
- ui32 Id() const {
- return Class;
- }
-
- void Load(IInputStream& in) override {
- if (!!InnerMsg_) {
- InnerMsg_->ParseFromArcadiaStream(&in);
- } else {
- TransferData(&in, &Cnull);
- }
- }
-
- void Save(IOutputStream& out) const override {
- Message_->SerializeToArcadiaStream(&out);
- }
-
- void SaveToBuffer(TBufferOutput& buf) const override {
- size_t messageSize = Message_->ByteSize();
- size_t before = buf.Buffer().Size();
- buf.Buffer().Advance(messageSize);
- Y_PROTOBUF_SUPPRESS_NODISCARD Message_->SerializeToArray(buf.Buffer().Data() + before, messageSize);
- }
-
- TStringBuf GetName() const override {
- return EventFactory_->NameById(Id());
- }
-
-private:
- void DoPrint(IOutputStream& out, EFieldOutputFlags flags) const override {
- EventFactory_->PrintEvent(Id(), Message_, out, flags);
- }
- void DoPrintJson(NJson::TJsonWriter& jsonWriter) const override {
- jsonWriter.OpenMap("EventBody");
- jsonWriter.Write("Type", GetName());
-
- jsonWriter.Write("Fields");
- NProtobufJson::Proto2Json(*GetProto(), jsonWriter, PROTO_2_JSON_CONFIG);
-
- jsonWriter.CloseMap();
- }
-
- const NProtoBuf::Message* GetProto() const override {
- if (Message_) {
- return Message_;
- }
-
- return UnknownEventMessage();
- }
-
-private:
- const NProtoBuf::Message* Message_ = nullptr;
- NProtoBuf::TEventFactory* EventFactory_;
- THolder<NProtoBuf::Message> InnerMsg_;
-
- friend class TEventLogFrame;
-};
-
-void TEventLogFrame::LogProtobufEvent(size_t eventId, const NProtoBuf::Message& ev) {
- TProtobufEvent event(Now().MicroSeconds(), eventId, ev);
-
- LogEventImpl(event);
-}
-
-void TEventLogFrame::LogProtobufEvent(TEventTimestamp timestamp, size_t eventId, const NProtoBuf::Message& ev) {
- TProtobufEvent event(timestamp, eventId, ev);
-
- LogEventImpl(event);
-}
-
-template <>
-void TEventLogFrame::DebugDump(const TProtobufEvent& ev) {
- static TMutex lock;
-
- with_lock (lock) {
- Cerr << ev.Timestamp << "\t" << ev.GetName() << "\t";
- ev.GetProto()->PrintJSON(Cerr);
- Cerr << Endl;
- }
-}
-
-#pragma pack(push, 1)
-struct TFrameHeaderData {
- char SyncField[COMPRESSED_LOG_FRAME_SYNC_DATA.size()];
- TCompressedFrameBaseHeader Header;
- TCompressedFrameHeader2 HeaderEx;
-};
-#pragma pack(pop)
-
-TEventLogFrame::TEventLogFrame(IEventLog& parentLog, bool needAlwaysSafeAdd, TWriteFrameCallbackPtr writeFrameCallback)
- : EvLog_(parentLog.HasNullBackend() ? nullptr : &parentLog)
- , NeedAlwaysSafeAdd_(needAlwaysSafeAdd)
- , ForceDump_(false)
- , WriteFrameCallback_(std::move(writeFrameCallback))
-{
- DoInit();
-}
-
-TEventLogFrame::TEventLogFrame(IEventLog* parentLog, bool needAlwaysSafeAdd, TWriteFrameCallbackPtr writeFrameCallback)
- : EvLog_(parentLog)
- , NeedAlwaysSafeAdd_(needAlwaysSafeAdd)
- , ForceDump_(false)
- , WriteFrameCallback_(std::move(writeFrameCallback))
-{
- if (EvLog_ && EvLog_->HasNullBackend()) {
- EvLog_ = nullptr;
- }
-
- DoInit();
-}
-
-TEventLogFrame::TEventLogFrame(bool needAlwaysSafeAdd, TWriteFrameCallbackPtr writeFrameCallback)
- : EvLog_(nullptr)
- , NeedAlwaysSafeAdd_(needAlwaysSafeAdd)
- , ForceDump_(false)
- , WriteFrameCallback_(std::move(writeFrameCallback))
-{
- DoInit();
-}
-
-void TEventLogFrame::Flush() {
- if (EvLog_ == nullptr)
- return;
-
- TBuffer& buf = Buf_.Buffer();
-
- if (buf.Empty()) {
- return;
- }
-
- EvLog_->WriteFrame(buf, StartTimestamp_, EndTimestamp_, WriteFrameCallback_, std::move(MetaFlags_));
-
- DoInit();
-
- return;
-}
-
-void TEventLogFrame::SafeFlush() {
- TGuard<TMutex> g(Mtx_);
- Flush();
-}
-
-void TEventLogFrame::AddEvent(TEventTimestamp timestamp) {
- if (timestamp < StartTimestamp_) {
- StartTimestamp_ = timestamp;
- }
-
- if (timestamp > EndTimestamp_) {
- EndTimestamp_ = timestamp;
- }
-}
-
-void TEventLogFrame::DoInit() {
- Buf_.Buffer().Clear();
-
- StartTimestamp_ = (TEventTimestamp)-1;
- EndTimestamp_ = 0;
-}
-
-void TEventLogFrame::VisitEvents(ILogFrameEventVisitor& visitor, IEventFactory* eventFactory) {
- const auto doVisit = [this, &visitor, eventFactory]() {
- TBuffer& buf = Buf_.Buffer();
-
- TBufferInput bufferInput(buf);
- TLengthLimitedInput limitedInput(&bufferInput, buf.size());
-
- TEventFilter EventFilter(false);
-
- while (limitedInput.Left()) {
- THolder<TEvent> event = DecodeEvent(limitedInput, true, 0, &EventFilter, eventFactory);
-
- visitor.Visit(*event);
- }
- };
- if (NeedAlwaysSafeAdd_) {
- TGuard<TMutex> g(Mtx_);
- doVisit();
- } else {
- doVisit();
- }
-}
-
-TSelfFlushLogFrame::TSelfFlushLogFrame(IEventLog& parentLog, bool needAlwaysSafeAdd, TWriteFrameCallbackPtr writeFrameCallback)
- : TEventLogFrame(parentLog, needAlwaysSafeAdd, std::move(writeFrameCallback))
-{
-}
-
-TSelfFlushLogFrame::TSelfFlushLogFrame(IEventLog* parentLog, bool needAlwaysSafeAdd, TWriteFrameCallbackPtr writeFrameCallback)
- : TEventLogFrame(parentLog, needAlwaysSafeAdd, std::move(writeFrameCallback))
-{
-}
-
-TSelfFlushLogFrame::TSelfFlushLogFrame(bool needAlwaysSafeAdd, TWriteFrameCallbackPtr writeFrameCallback)
- : TEventLogFrame(needAlwaysSafeAdd, std::move(writeFrameCallback))
-{
-}
-
-TSelfFlushLogFrame::~TSelfFlushLogFrame() {
- try {
- Flush();
- } catch (...) {
- }
-}
-
-IEventLog::~IEventLog() {
-}
-
-static THolder<TLogBackend> ConstructBackend(const TString& fileName, const TEventLogBackendOptions& backendOpts) {
- try {
- THolder<TLogBackend> backend;
- if (backendOpts.UseSyncPageCacheBackend) {
- backend = MakeHolder<TSyncPageCacheFileLogBackend>(fileName, backendOpts.SyncPageCacheBackendBufferSize, backendOpts.SyncPageCacheBackendMaxPendingSize);
- } else {
- backend = MakeHolder<TFileLogBackend>(fileName);
- }
- return MakeHolder<TReopenLogBackend>(std::move(backend));
- } catch (...) {
- Cdbg << "Warning: Cannot open event log '" << fileName << "': " << CurrentExceptionMessage() << "." << Endl;
- }
-
- return MakeHolder<TNullLogBackend>();
-}
-
-TEventLog::TEventLog(const TString& fileName, TEventLogFormat contentFormat, const TEventLogBackendOptions& backendOpts, TMaybe<TEventLogFormat> logFormat)
- : Log_(ConstructBackend(fileName, backendOpts))
- , ContentFormat_(contentFormat)
- , LogFormat_(logFormat.Defined() ? *logFormat : COMPRESSED_LOG_FORMAT_V4)
- , HasNullBackend_(Log_.IsNullLog())
- , Lz4hcCodec_(NBlockCodecs::Codec("lz4hc"))
- , ZstdCodec_(NBlockCodecs::Codec("zstd_1"))
-{
- Y_ENSURE(LogFormat_ == COMPRESSED_LOG_FORMAT_V4 || LogFormat_ == COMPRESSED_LOG_FORMAT_V5);
-
- if (contentFormat & 0xff000000) {
- ythrow yexception() << "wrong compressed event log content format code (" << contentFormat << ")";
- }
-}
-
-TEventLog::TEventLog(const TString& fileName, TEventLogFormat contentFormat, const TEventLogBackendOptions& backendOpts)
- : TEventLog(fileName, contentFormat, backendOpts, COMPRESSED_LOG_FORMAT_V4)
-{
-}
-
-TEventLog::TEventLog(const TLog& log, TEventLogFormat contentFormat, TEventLogFormat logFormat)
- : Log_(log)
- , ContentFormat_(contentFormat)
- , LogFormat_(logFormat)
- , HasNullBackend_(Log_.IsNullLog())
- , Lz4hcCodec_(NBlockCodecs::Codec("lz4hc"))
- , ZstdCodec_(NBlockCodecs::Codec("zstd_1"))
-{
- if (contentFormat & 0xff000000) {
- ythrow yexception() << "wrong compressed event log content format code (" << contentFormat << ")";
- }
-}
-
-TEventLog::TEventLog(TEventLogFormat contentFormat, TEventLogFormat logFormat)
- : Log_(MakeHolder<TNullLogBackend>())
- , ContentFormat_(contentFormat)
- , LogFormat_(logFormat)
- , HasNullBackend_(true)
- , Lz4hcCodec_(NBlockCodecs::Codec("lz4hc"))
- , ZstdCodec_(NBlockCodecs::Codec("zstd_1"))
-{
- if (contentFormat & 0xff000000) {
- ythrow yexception() << "wrong compressed event log content format code (" << contentFormat << ")";
- }
-}
-
-TEventLog::~TEventLog() {
-}
-
-void TEventLog::ReopenLog() {
- Log_.ReopenLog();
-}
-
-void TEventLog::CloseLog() {
- Log_.CloseLog();
-}
-
-void TEventLog::Flush() {
-}
-
-namespace {
- class TOnExceptionAction {
- public:
- TOnExceptionAction(std::function<void()>&& f)
- : F_(std::move(f))
- {
- }
-
- ~TOnExceptionAction() {
- if (F_ && UncaughtException()) {
- try {
- F_();
- } catch (...) {
- }
- }
- }
-
- private:
- std::function<void()> F_;
- };
-}
-
-void TEventLog::WriteFrame(TBuffer& buffer,
- TEventTimestamp startTimestamp,
- TEventTimestamp endTimestamp,
- TWriteFrameCallbackPtr writeFrameCallback,
- TLogRecord::TMetaFlags metaFlags) {
- Y_ENSURE(LogFormat_ == COMPRESSED_LOG_FORMAT_V4 || LogFormat_ == COMPRESSED_LOG_FORMAT_V5);
-
- TBuffer& b1 = buffer;
-
- size_t maxCompressedLength = (LogFormat_ == COMPRESSED_LOG_FORMAT_V4) ? b1.Size() + 256 : ZstdCodec_->MaxCompressedLength(b1);
-
- // Reserve enough memory to minimize reallocs
- TBufferOutput outbuf(sizeof(TFrameHeaderData) + maxCompressedLength);
- TBuffer& b2 = outbuf.Buffer();
- b2.Proceed(sizeof(TFrameHeaderData));
-
- {
- TFrameHeaderData& hdr = *reinterpret_cast<TFrameHeaderData*>(b2.data());
-
- memcpy(hdr.SyncField, COMPRESSED_LOG_FRAME_SYNC_DATA.data(), COMPRESSED_LOG_FRAME_SYNC_DATA.size());
- hdr.Header.Format = (LogFormat_ << 24) | (ContentFormat_ & 0xffffff);
- hdr.Header.FrameId = GenerateFrameId();
- hdr.HeaderEx.UncompressedDatalen = (ui32)b1.Size();
- hdr.HeaderEx.StartTimestamp = startTimestamp;
- hdr.HeaderEx.EndTimestamp = endTimestamp;
- hdr.HeaderEx.PayloadChecksum = 0;
- hdr.HeaderEx.CompressorVersion = 0;
- }
-
- if (LogFormat_ == COMPRESSED_LOG_FORMAT_V4) {
- TBuffer encoded(b1.Size() + sizeof(TFrameHeaderData) + 256);
- Lz4hcCodec_->Encode(b1, encoded);
-
- TZLibCompress compr(&outbuf, ZLib::ZLib, 6, 2048);
- compr.Write(encoded.data(), encoded.size());
- compr.Finish();
- } else {
- b2.Advance(ZstdCodec_->Compress(b1, b2.Pos()));
- }
-
- {
- const size_t k = sizeof(TCompressedFrameBaseHeader) + COMPRESSED_LOG_FRAME_SYNC_DATA.size();
- TFrameHeaderData& hdr = *reinterpret_cast<TFrameHeaderData*>(b2.data());
- hdr.Header.Length = static_cast<ui32>(b2.size() - k);
- hdr.HeaderEx.PayloadChecksum = MurmurHash<ui32>(b2.data() + sizeof(TFrameHeaderData), b2.size() - sizeof(TFrameHeaderData));
-
- const size_t n = sizeof(TFrameHeaderData) - (COMPRESSED_LOG_FRAME_SYNC_DATA.size() + sizeof(hdr.HeaderEx.HeaderChecksum));
- hdr.HeaderEx.HeaderChecksum = MurmurHash<ui32>(b2.data() + COMPRESSED_LOG_FRAME_SYNC_DATA.size(), n);
- }
-
- const TBuffer& frameData = outbuf.Buffer();
-
- TOnExceptionAction actionCallback([this] {
- if (ErrorCallback_) {
- ErrorCallback_->OnWriteError();
- }
- });
-
- if (writeFrameCallback) {
- writeFrameCallback->OnAfterCompress(frameData, startTimestamp, endTimestamp);
- }
-
- Log_.Write(frameData.Data(), frameData.Size(), std::move(metaFlags));
- if (SuccessCallback_) {
- SuccessCallback_->OnWriteSuccess(frameData);
- }
-}
-
-TEvent* TProtobufEventFactory::CreateLogEvent(TEventClass c) {
- return new TProtobufEvent(c, EventFactory_);
-}
-
-TEventClass TProtobufEventFactory::ClassByName(TStringBuf name) const {
- return EventFactory_->IdByName(name);
-}
-
-TEventClass TProtobufEventFactory::EventClassBegin() const {
- const auto& items = EventFactory_->FactoryItems();
-
- if (items.empty()) {
- return static_cast<TEventClass>(0);
- }
-
- return static_cast<TEventClass>(items.begin()->first);
-}
-
-TEventClass TProtobufEventFactory::EventClassEnd() const {
- const auto& items = EventFactory_->FactoryItems();
-
- if (items.empty()) {
- return static_cast<TEventClass>(0);
- }
-
- return static_cast<TEventClass>(items.rbegin()->first + 1);
-}
-
-namespace NEvClass {
- IEventFactory* Factory() {
- return Singleton<TProtobufEventFactory>();
- }
-
- IEventProcessor* Processor() {
- return Singleton<TProtobufEventProcessor>();
- }
-}
-
-const NProtoBuf::Message* TUnknownEvent::GetProto() const {
- return UnknownEventMessage();
-}
-
-TStringBuf TUnknownEvent::GetName() const {
- return TStringBuf("UnknownEvent");
-}
-
-void TUnknownEvent::DoPrintJson(NJson::TJsonWriter& jsonWriter) const {
- jsonWriter.OpenMap("EventBody");
- jsonWriter.Write("Type", GetName());
- jsonWriter.Write("EventId", (size_t)Class);
- jsonWriter.CloseMap();
-}
-
-TStringBuf TEndOfFrameEvent::GetName() const {
- return TStringBuf("EndOfFrame");
-}
-
-const NProtoBuf::Message* TEndOfFrameEvent::GetProto() const {
- return Singleton<NEventLogInternal::TEndOfFrameEvent>();
-}
-
-void TEndOfFrameEvent::DoPrintJson(NJson::TJsonWriter& jsonWriter) const {
- jsonWriter.OpenMap("EventBody");
- jsonWriter.Write("Type", GetName());
- jsonWriter.OpenMap("Fields");
- jsonWriter.CloseMap();
- jsonWriter.CloseMap();
-}
-
-THolder<TEvent> MakeProtobufLogEvent(TEventTimestamp ts, TEventClass eventId, google::protobuf::Message& ev) {
- return MakeHolder<TProtobufEvent>(ts, eventId, ev);
-}
diff --git a/library/cpp/eventlog/eventlog.h b/library/cpp/eventlog/eventlog.h
deleted file mode 100644
index 45c2dfb17f..0000000000
--- a/library/cpp/eventlog/eventlog.h
+++ /dev/null
@@ -1,623 +0,0 @@
-#pragma once
-
-#include "eventlog_int.h"
-#include "event_field_output.h"
-#include "events_extension.h"
-
-#include <library/cpp/blockcodecs/codecs.h>
-#include <library/cpp/logger/all.h>
-
-#include <google/protobuf/message.h>
-
-#include <util/datetime/base.h>
-#include <util/generic/ptr.h>
-#include <util/generic/string.h>
-#include <util/stream/output.h>
-#include <util/stream/buffer.h>
-#include <util/stream/str.h>
-#include <util/system/mutex.h>
-#include <util/stream/output.h>
-#include <util/system/env.h>
-#include <util/system/unaligned_mem.h>
-#include <util/ysaveload.h>
-
-#include <cstdlib>
-
-namespace NJson {
- class TJsonWriter;
-}
-
-class IEventLog;
-
-class TEvent : public TThrRefBase {
-public:
- enum class TOutputFormat {
- TabSeparated,
- TabSeparatedRaw, // disables escaping
- Json
- };
-
- struct TOutputOptions {
- TOutputFormat OutputFormat = TOutputFormat::TabSeparated;
- // Dump some fields (e.g. timestamp) in more human-readable format
- bool HumanReadable = false;
-
- TOutputOptions(TOutputFormat outputFormat = TOutputFormat::TabSeparated)
- : OutputFormat(outputFormat)
- {
- }
-
- TOutputOptions(TOutputFormat outputFormat, bool humanReadable)
- : OutputFormat(outputFormat)
- , HumanReadable(humanReadable)
- {
- }
- };
-
- struct TEventState {
- TEventTimestamp FrameStartTime = 0;
- TEventTimestamp PrevEventTime = 0;
- TEventState() {
- }
- };
-
- TEvent(TEventClass c, TEventTimestamp t)
- : Class(c)
- , Timestamp(t)
- {
- }
-
- virtual ~TEvent() = default;
-
- // Note, that descendants MUST have Save() & Load() methods to alter
- // only its new variables, not the base class!
- virtual void Save(IOutputStream& out) const = 0;
- virtual void SaveToBuffer(TBufferOutput& out) const {
- Save(out);
- }
-
- // Note, that descendants MUST have Save() & Load() methods to alter
- // only its new variables, not the base class!
- virtual void Load(IInputStream& i) = 0;
-
- virtual TStringBuf GetName() const = 0;
- virtual const NProtoBuf::Message* GetProto() const = 0;
-
- void Print(IOutputStream& out, const TOutputOptions& options = TOutputOptions(), const TEventState& eventState = TEventState()) const;
- void PrintHeader(IOutputStream& out, const TOutputOptions& options, const TEventState& eventState) const;
-
- TString ToString() const {
- TStringStream buff;
- Print(buff);
- return buff.Str();
- }
-
- void FullSaveToBuffer(TBufferOutput& buf) const {
- SaveMessageHeader(buf);
- this->SaveToBuffer(buf);
- }
-
- void FullSave(IOutputStream& o) const {
- SaveMessageHeader(o);
- this->Save(o);
- }
-
- void FullLoad(IInputStream& i) {
- ::Load(&i, Timestamp);
- ::Load(&i, Class);
- this->Load(i);
- }
-
- template <class T>
- const T* Get() const {
- return static_cast<const T*>(this->GetProto());
- }
-
- TEventClass Class;
- TEventTimestamp Timestamp;
- ui32 FrameId = 0;
-
-private:
- void SaveMessageHeader(IOutputStream& out) const {
- ::Save(&out, Timestamp);
- ::Save(&out, Class);
- }
-
- virtual void DoPrint(IOutputStream& out, EFieldOutputFlags flags) const = 0;
- virtual void DoPrintJson(NJson::TJsonWriter& jsonWriter) const = 0;
-
- void PrintJsonHeader(NJson::TJsonWriter& jsonWriter) const;
-};
-
-using TEventPtr = TIntrusivePtr<TEvent>;
-using TConstEventPtr = TIntrusiveConstPtr<TEvent>;
-
-class IEventProcessor {
-public:
- virtual void SetOptions(const TEvent::TOutputOptions& options) {
- Options_ = options;
- }
- virtual void ProcessEvent(const TEvent* ev) = 0;
- virtual bool CheckedProcessEvent(const TEvent* ev) {
- ProcessEvent(ev);
- return true;
- }
- virtual ~IEventProcessor() = default;
-
-protected:
- TEvent::TOutputOptions Options_;
-};
-
-class IEventFactory {
-public:
- virtual TEvent* CreateLogEvent(TEventClass c) = 0;
- virtual TEventLogFormat CurrentFormat() = 0;
- virtual TEventClass ClassByName(TStringBuf name) const = 0;
- virtual TEventClass EventClassBegin() const = 0;
- virtual TEventClass EventClassEnd() const = 0;
- virtual ~IEventFactory() = default;
-};
-
-class TUnknownEvent: public TEvent {
-public:
- TUnknownEvent(TEventTimestamp ts, TEventClass cls)
- : TEvent(cls, ts)
- {
- }
-
- ~TUnknownEvent() override = default;
-
- void Save(IOutputStream& /* o */) const override {
- ythrow yexception() << "TUnknownEvent cannot be saved";
- }
-
- void Load(IInputStream& /* i */) override {
- ythrow yexception() << "TUnknownEvent cannot be loaded";
- }
-
- TStringBuf GetName() const override;
-
-private:
- void DoPrint(IOutputStream& out, EFieldOutputFlags) const override {
- out << GetName() << "\t" << (size_t)Class;
- }
-
- void DoPrintJson(NJson::TJsonWriter& jsonWriter) const override;
-
- const NProtoBuf::Message* GetProto() const override;
-};
-
-class TEndOfFrameEvent: public TEvent {
-public:
- enum {
- EventClass = 0
- };
-
- TEndOfFrameEvent(TEventTimestamp ts)
- : TEvent(TEndOfFrameEvent::EventClass, ts)
- {
- }
-
- ~TEndOfFrameEvent() override = default;
-
- void Save(IOutputStream& o) const override {
- (void)o;
- ythrow yexception() << "TEndOfFrameEvent cannot be saved";
- }
-
- void Load(IInputStream& i) override {
- (void)i;
- ythrow yexception() << "TEndOfFrameEvent cannot be loaded";
- }
-
- TStringBuf GetName() const override;
-
-private:
- void DoPrint(IOutputStream& out, EFieldOutputFlags) const override {
- out << GetName();
- }
- void DoPrintJson(NJson::TJsonWriter& jsonWriter) const override;
-
- const NProtoBuf::Message* GetProto() const override;
-};
-
-class ILogFrameEventVisitor {
-public:
- virtual ~ILogFrameEventVisitor() = default;
-
- virtual void Visit(const TEvent& event) = 0;
-};
-
-class IWriteFrameCallback : public TAtomicRefCount<IWriteFrameCallback> {
-public:
- virtual ~IWriteFrameCallback() = default;
-
- virtual void OnAfterCompress(const TBuffer& compressedFrame, TEventTimestamp startTimestamp, TEventTimestamp endTimestamp) = 0;
-};
-
-using TWriteFrameCallbackPtr = TIntrusivePtr<IWriteFrameCallback>;
-
-class TEventLogFrame {
-public:
- TEventLogFrame(bool needAlwaysSafeAdd = false, TWriteFrameCallbackPtr writeFrameCallback = nullptr);
- TEventLogFrame(IEventLog& parentLog, bool needAlwaysSafeAdd = false, TWriteFrameCallbackPtr writeFrameCallback = nullptr);
- TEventLogFrame(IEventLog* parentLog, bool needAlwaysSafeAdd = false, TWriteFrameCallbackPtr writeFrameCallback = nullptr);
-
- virtual ~TEventLogFrame() = default;
-
- void Flush();
- void SafeFlush();
-
- void ForceDump() {
- ForceDump_ = true;
- }
-
- template <class T>
- inline void LogEvent(const T& ev) {
- if (NeedAlwaysSafeAdd_) {
- SafeLogEvent(ev);
- } else {
- UnSafeLogEvent(ev);
- }
- }
-
- template <class T>
- inline void LogEvent(TEventTimestamp timestamp, const T& ev) {
- if (NeedAlwaysSafeAdd_) {
- SafeLogEvent(timestamp, ev);
- } else {
- UnSafeLogEvent(timestamp, ev);
- }
- }
-
- template <class T>
- inline void UnSafeLogEvent(const T& ev) {
- if (!IsEventIgnored(ev.ID))
- LogProtobufEvent(ev.ID, ev);
- }
-
- template <class T>
- inline void UnSafeLogEvent(TEventTimestamp timestamp, const T& ev) {
- if (!IsEventIgnored(ev.ID))
- LogProtobufEvent(timestamp, ev.ID, ev);
- }
-
- template <class T>
- inline void SafeLogEvent(const T& ev) {
- if (!IsEventIgnored(ev.ID)) {
- TGuard<TMutex> g(Mtx_);
- LogProtobufEvent(ev.ID, ev);
- }
- }
-
- template <class T>
- inline void SafeLogEvent(TEventTimestamp timestamp, const T& ev) {
- if (!IsEventIgnored(ev.ID)) {
- TGuard<TMutex> g(Mtx_);
- LogProtobufEvent(timestamp, ev.ID, ev);
- }
- }
-
- void VisitEvents(ILogFrameEventVisitor& visitor, IEventFactory* eventFactory);
-
- inline bool IsEventIgnored(size_t eventId) const {
- Y_UNUSED(eventId); // in future we might want to selectively discard only some kinds of messages
- return !IsDebugModeEnabled() && EvLog_ == nullptr && !ForceDump_;
- }
-
- void Enable(IEventLog& evLog) {
- EvLog_ = &evLog;
- }
-
- void Disable() {
- EvLog_ = nullptr;
- }
-
- void SetNeedAlwaysSafeAdd(bool val) {
- NeedAlwaysSafeAdd_ = val;
- }
-
- void SetWriteFrameCallback(TWriteFrameCallbackPtr writeFrameCallback) {
- WriteFrameCallback_ = writeFrameCallback;
- }
-
- void AddMetaFlag(const TString& key, const TString& value) {
- if (NeedAlwaysSafeAdd_) {
- TGuard<TMutex> g(Mtx_);
- MetaFlags_.emplace_back(key, value);
- } else {
- MetaFlags_.emplace_back(key, value);
- }
- }
-
-protected:
- void LogProtobufEvent(size_t eventId, const NProtoBuf::Message& ev);
- void LogProtobufEvent(TEventTimestamp timestamp, size_t eventId, const NProtoBuf::Message& ev);
-
-private:
- static bool IsDebugModeEnabled() {
- static struct TSelector {
- bool Flag;
-
- TSelector()
- : Flag(GetEnv("EVLOG_DEBUG") == TStringBuf("1"))
- {
- }
- } selector;
-
- return selector.Flag;
- }
-
- template <class T>
- void DebugDump(const T& ev);
-
- // T must be a descendant of NEvClass::TEvent
- template <class T>
- inline void LogEventImpl(const T& ev) {
- if (EvLog_ != nullptr || ForceDump_) {
- TBuffer& b = Buf_.Buffer();
- size_t lastSize = b.size();
- ::Save(&Buf_, ui32(0));
- ev.FullSaveToBuffer(Buf_);
- WriteUnaligned<ui32>(b.data() + lastSize, (ui32)(b.size() - lastSize));
- AddEvent(ev.Timestamp);
- }
-
- if (IsDebugModeEnabled()) {
- DebugDump(ev);
- }
- }
-
- void AddEvent(TEventTimestamp timestamp);
- void DoInit();
-
-private:
- TBufferOutput Buf_;
- TEventTimestamp StartTimestamp_, EndTimestamp_;
- IEventLog* EvLog_;
- TMutex Mtx_;
- bool NeedAlwaysSafeAdd_;
- bool ForceDump_;
- TWriteFrameCallbackPtr WriteFrameCallback_;
- TLogRecord::TMetaFlags MetaFlags_;
- friend class TEventRecord;
-};
-
-class TSelfFlushLogFrame: public TEventLogFrame, public TAtomicRefCount<TSelfFlushLogFrame> {
-public:
- TSelfFlushLogFrame(bool needAlwaysSafeAdd = false, TWriteFrameCallbackPtr writeFrameCallback = nullptr);
- TSelfFlushLogFrame(IEventLog& parentLog, bool needAlwaysSafeAdd = false, TWriteFrameCallbackPtr writeFrameCallback = nullptr);
- TSelfFlushLogFrame(IEventLog* parentLog, bool needAlwaysSafeAdd = false, TWriteFrameCallbackPtr writeFrameCallback = nullptr);
-
- virtual ~TSelfFlushLogFrame();
-};
-
-using TSelfFlushLogFramePtr = TIntrusivePtr<TSelfFlushLogFrame>;
-
-class IEventLog: public TAtomicRefCount<IEventLog> {
-public:
- class IErrorCallback {
- public:
- virtual ~IErrorCallback() {
- }
-
- virtual void OnWriteError() = 0;
- };
-
- class ISuccessCallback {
- public:
- virtual ~ISuccessCallback() {
- }
-
- virtual void OnWriteSuccess(const TBuffer& frameData) = 0;
- };
-
- virtual ~IEventLog();
-
- virtual void ReopenLog() = 0;
- virtual void CloseLog() = 0;
- virtual void Flush() = 0;
- virtual void SetErrorCallback(IErrorCallback*) {
- }
- virtual void SetSuccessCallback(ISuccessCallback*) {
- }
-
- template <class T>
- void LogEvent(const T& ev) {
- TEventLogFrame frame(*this);
- frame.LogEvent(ev);
- frame.Flush();
- }
-
- virtual bool HasNullBackend() const = 0;
-
- virtual void WriteFrame(TBuffer& buffer,
- TEventTimestamp startTimestamp,
- TEventTimestamp endTimestamp,
- TWriteFrameCallbackPtr writeFrameCallback = nullptr,
- TLogRecord::TMetaFlags metaFlags = {}) = 0;
-};
-
-struct TEventLogBackendOptions {
- bool UseSyncPageCacheBackend = false;
- size_t SyncPageCacheBackendBufferSize = 0;
- size_t SyncPageCacheBackendMaxPendingSize = 0;
-};
-
-class TEventLog: public IEventLog {
-public:
- /*
- * Параметр contentformat указывает формат контента лога, например какие могут в логе
- * встретится классы событий, какие параметры у этих событий, и пр. Старший байт параметра
- * должен быть нулевым.
- */
- TEventLog(const TString& fileName, TEventLogFormat contentFormat, const TEventLogBackendOptions& backendOpts, TMaybe<TEventLogFormat> logFormat);
- TEventLog(const TString& fileName, TEventLogFormat contentFormat, const TEventLogBackendOptions& backendOpts = {});
- TEventLog(const TLog& log, TEventLogFormat contentFormat, TEventLogFormat logFormat = COMPRESSED_LOG_FORMAT_V4);
- TEventLog(TEventLogFormat contentFormat, TEventLogFormat logFormat = COMPRESSED_LOG_FORMAT_V4);
-
- ~TEventLog() override;
-
- void ReopenLog() override;
- void CloseLog() override;
- void Flush() override;
- void SetErrorCallback(IErrorCallback* errorCallback) override {
- ErrorCallback_ = errorCallback;
- }
- void SetSuccessCallback(ISuccessCallback* successCallback) override {
- SuccessCallback_ = successCallback;
- }
-
- template <class T>
- void LogEvent(const T& ev) {
- TEventLogFrame frame(*this);
- frame.LogEvent(ev);
- frame.Flush();
- }
-
- bool HasNullBackend() const override {
- return HasNullBackend_;
- }
-
- void WriteFrame(TBuffer& buffer,
- TEventTimestamp startTimestamp,
- TEventTimestamp endTimestamp,
- TWriteFrameCallbackPtr writeFrameCallback = nullptr,
- TLogRecord::TMetaFlags metaFlags = {}) override;
-
-private:
- mutable TLog Log_;
- TEventLogFormat ContentFormat_;
- const TEventLogFormat LogFormat_;
- bool HasNullBackend_;
- const NBlockCodecs::ICodec* const Lz4hcCodec_;
- const NBlockCodecs::ICodec* const ZstdCodec_;
- IErrorCallback* ErrorCallback_ = nullptr;
- ISuccessCallback* SuccessCallback_ = nullptr;
-};
-
-using TEventLogPtr = TIntrusivePtr<IEventLog>;
-
-class TEventLogWithSlave: public IEventLog {
-public:
- TEventLogWithSlave(IEventLog& parentLog)
- : Slave_(&parentLog)
- {
- }
-
- TEventLogWithSlave(const TEventLogPtr& parentLog)
- : SlavePtr_(parentLog)
- , Slave_(SlavePtr_.Get())
- {
- }
-
- ~TEventLogWithSlave() override {
- try {
- Slave().Flush();
- } catch (...) {
- }
- }
-
- void Flush() override {
- Slave().Flush();
- }
-
- void ReopenLog() override {
- return Slave().ReopenLog();
- }
- void CloseLog() override {
- return Slave().CloseLog();
- }
-
- bool HasNullBackend() const override {
- return Slave().HasNullBackend();
- }
-
- void WriteFrame(TBuffer& buffer,
- TEventTimestamp startTimestamp,
- TEventTimestamp endTimestamp,
- TWriteFrameCallbackPtr writeFrameCallback = nullptr,
- TLogRecord::TMetaFlags metaFlags = {}) override {
- Slave().WriteFrame(buffer, startTimestamp, endTimestamp, writeFrameCallback, std::move(metaFlags));
- }
-
- void SetErrorCallback(IErrorCallback* errorCallback) override {
- Slave().SetErrorCallback(errorCallback);
- }
-
- void SetSuccessCallback(ISuccessCallback* successCallback) override {
- Slave().SetSuccessCallback(successCallback);
- }
-
-protected:
- inline IEventLog& Slave() const {
- return *Slave_;
- }
-
-private:
- TEventLogPtr SlavePtr_;
- IEventLog* Slave_ = nullptr;
-};
-
-extern TAtomic eventlogFrameCounter;
-
-class TProtobufEventProcessor: public IEventProcessor {
-public:
- void ProcessEvent(const TEvent* ev) override final {
- ProcessEvent(ev, &Cout);
- }
-
- void ProcessEvent(const TEvent* ev, IOutputStream *out) {
- UpdateEventState(ev);
- DoProcessEvent(ev, out);
- EventState_.PrevEventTime = ev->Timestamp;
- }
-protected:
- virtual void DoProcessEvent(const TEvent * ev, IOutputStream *out) {
- ev->Print(*out, Options_, EventState_);
- (*out) << Endl;
- }
- ui32 CurrentFrameId_ = Max<ui32>();
- TEvent::TEventState EventState_;
-
-private:
- void UpdateEventState(const TEvent *ev) {
- if (ev->FrameId != CurrentFrameId_) {
- EventState_.FrameStartTime = ev->Timestamp;
- EventState_.PrevEventTime = ev->Timestamp;
- CurrentFrameId_ = ev->FrameId;
- }
- }
-};
-
-class TProtobufEventFactory: public IEventFactory {
-public:
- TProtobufEventFactory(NProtoBuf::TEventFactory* factory = NProtoBuf::TEventFactory::Instance())
- : EventFactory_(factory)
- {
- }
-
- TEvent* CreateLogEvent(TEventClass c) override;
-
- TEventLogFormat CurrentFormat() override {
- return 0;
- }
-
- TEventClass ClassByName(TStringBuf name) const override;
-
- TEventClass EventClassBegin() const override;
-
- TEventClass EventClassEnd() const override;
-
- ~TProtobufEventFactory() override = default;
-
-private:
- NProtoBuf::TEventFactory* EventFactory_;
-};
-
-THolder<TEvent> MakeProtobufLogEvent(TEventTimestamp ts, TEventClass eventId, google::protobuf::Message& ev);
-
-namespace NEvClass {
- IEventFactory* Factory();
- IEventProcessor* Processor();
-}
diff --git a/library/cpp/eventlog/eventlog_int.cpp b/library/cpp/eventlog/eventlog_int.cpp
deleted file mode 100644
index faa8c42cbe..0000000000
--- a/library/cpp/eventlog/eventlog_int.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "eventlog_int.h"
-
-#include <util/string/cast.h>
-
-TMaybe<TEventLogFormat> ParseEventLogFormat(TStringBuf str) {
- EEventLogFormat format;
- if (TryFromString(str, format)) {
- return static_cast<TEventLogFormat>(format);
- } else {
- return {};
- }
-}
diff --git a/library/cpp/eventlog/eventlog_int.h b/library/cpp/eventlog/eventlog_int.h
deleted file mode 100644
index eb00fecfab..0000000000
--- a/library/cpp/eventlog/eventlog_int.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#pragma once
-
-#include <util/stream/output.h>
-#include <util/generic/maybe.h>
-#include <util/generic/utility.h>
-#include <util/generic/yexception.h>
-#include <util/ysaveload.h>
-
-using TEventClass = ui32;
-using TEventLogFormat = ui32;
-using TEventTimestamp = ui64;
-
-constexpr TStringBuf COMPRESSED_LOG_FRAME_SYNC_DATA =
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\xfe\x00\x00\xff\xff\x00\x00\xff\xff\x00"
- "\x00\xff\xff\x00\x00\xff\xff\x00\x00\xff\xff\x00\x00\xff"
- "\xff\x00\x00\xff\xff\x00\x00\xff"sv;
-
-static_assert(COMPRESSED_LOG_FRAME_SYNC_DATA.size() == 64);
-
-/*
- * Коды форматов логов. Форматом лога считается формат служебных
- * структур лога. К примеру формат заголовка, наличие компрессии, и т.д.
- * Имеет значение только 1 младший байт.
- */
-
-enum EEventLogFormat : TEventLogFormat {
- // Формат версии 1. Используется компрессор LZQ.
- COMPRESSED_LOG_FORMAT_V1 = 1,
-
- // Формат версии 2. Используется компрессор ZLIB. Добавлены CRC заголовка и данных,
- // поле типа компрессора.
- COMPRESSED_LOG_FORMAT_V2 = 2,
-
- // Формат версии 3. Используется компрессор ZLIB. В начинке фреймов перед каждым событием добавлен его размер.
- COMPRESSED_LOG_FORMAT_V3 = 3,
-
- // Lz4hc codec + zlib
- COMPRESSED_LOG_FORMAT_V4 = 4 /* "zlib_lz4" */,
-
- // zstd
- COMPRESSED_LOG_FORMAT_V5 = 5 /* "zstd" */,
-};
-
-TMaybe<TEventLogFormat> ParseEventLogFormat(TStringBuf str);
-
-#pragma pack(push, 1)
-
-struct TCompressedFrameBaseHeader {
- TEventLogFormat Format;
- ui32 Length; // Длина остатка фрейма в байтах, после этого заголовка
- ui32 FrameId;
-};
-
-struct TCompressedFrameHeader {
- TEventTimestamp StartTimestamp;
- TEventTimestamp EndTimestamp;
- ui32 UncompressedDatalen; // Длина данных, которые были закомпрессированы
- ui32 PayloadChecksum; // В логе версии 1 поле не используется
-};
-
-struct TCompressedFrameHeader2: public TCompressedFrameHeader {
- ui8 CompressorVersion; // Сейчас не используется
- ui32 HeaderChecksum;
-};
-
-#pragma pack(pop)
-
-Y_DECLARE_PODTYPE(TCompressedFrameBaseHeader);
-Y_DECLARE_PODTYPE(TCompressedFrameHeader);
-Y_DECLARE_PODTYPE(TCompressedFrameHeader2);
diff --git a/library/cpp/eventlog/events_extension.h b/library/cpp/eventlog/events_extension.h
deleted file mode 100644
index 0cf062f959..0000000000
--- a/library/cpp/eventlog/events_extension.h
+++ /dev/null
@@ -1,161 +0,0 @@
-#pragma once
-
-#include "event_field_output.h"
-
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/message.h>
-
-#include <library/cpp/threading/atomic/bool.h>
-#include <library/cpp/string_utils/base64/base64.h>
-
-#include <util/generic/map.h>
-#include <util/generic/deque.h>
-#include <util/generic/singleton.h>
-#include <util/string/hex.h>
-#include <util/system/guard.h>
-#include <util/system/mutex.h>
-
-namespace NProtoBuf {
- class TEventFactory {
- public:
- typedef ::google::protobuf::Message Message;
- typedef void (*TEventSerializer)(const Message* event, IOutputStream& output, EFieldOutputFlags flags);
- typedef void (*TRegistrationFunc)();
-
- private:
- class TFactoryItem {
- public:
- TFactoryItem(const Message* prototype, const TEventSerializer serializer)
- : Prototype_(prototype)
- , Serializer_(serializer)
- {
- }
-
- TStringBuf GetName() const {
- return Prototype_->GetDescriptor()->name();
- }
-
- Message* Create() const {
- return Prototype_->New();
- }
-
- void PrintEvent(const Message* event, IOutputStream& out, EFieldOutputFlags flags) const {
- (*Serializer_)(event, out, flags);
- }
-
- private:
- const Message* Prototype_;
- const TEventSerializer Serializer_;
- };
-
- typedef TMap<size_t, TFactoryItem> TFactoryMap;
-
- public:
- TEventFactory()
- : FactoryItems_()
- {
- }
-
- void ScheduleRegistration(TRegistrationFunc func) {
- EventRegistrators_.push_back(func);
- }
-
- void RegisterEvent(size_t eventId, const Message* prototype, const TEventSerializer serializer) {
- FactoryItems_.insert(std::make_pair(eventId, TFactoryItem(prototype, serializer)));
- }
-
- size_t IdByName(TStringBuf eventname) {
- DelayedRegistration();
- for (TFactoryMap::const_iterator it = FactoryItems_.begin(); it != FactoryItems_.end(); ++it) {
- if (it->second.GetName() == eventname)
- return it->first;
- }
-
- ythrow yexception() << "do not know event '" << eventname << "'";
- }
-
- TStringBuf NameById(size_t id) {
- DelayedRegistration();
- TFactoryMap::const_iterator it = FactoryItems_.find(id);
- return it != FactoryItems_.end() ? it->second.GetName() : TStringBuf();
- }
-
- Message* CreateEvent(size_t eventId) {
- DelayedRegistration();
- TFactoryMap::const_iterator it = FactoryItems_.find(eventId);
-
- if (it != FactoryItems_.end()) {
- return it->second.Create();
- }
-
- return nullptr;
- }
-
- const TMap<size_t, TFactoryItem>& FactoryItems() {
- DelayedRegistration();
- return FactoryItems_;
- }
-
- void PrintEvent(
- size_t eventId,
- const Message* event,
- IOutputStream& output,
- EFieldOutputFlags flags = {}) {
- DelayedRegistration();
- TFactoryMap::const_iterator it = FactoryItems_.find(eventId);
-
- if (it != FactoryItems_.end()) {
- it->second.PrintEvent(event, output, flags);
- }
- }
-
- static TEventFactory* Instance() {
- return Singleton<TEventFactory>();
- }
-
- private:
- void DelayedRegistration() {
- if (!DelayedRegistrationDone_) {
- TGuard<TMutex> guard(MutexEventRegistrators_);
- Y_UNUSED(guard);
- while (!EventRegistrators_.empty()) {
- EventRegistrators_.front()();
- EventRegistrators_.pop_front();
- }
- DelayedRegistrationDone_ = true;
- }
- }
-
- private:
- TMap<size_t, TFactoryItem> FactoryItems_;
- TDeque<TRegistrationFunc> EventRegistrators_;
- NAtomic::TBool DelayedRegistrationDone_ = false;
- TMutex MutexEventRegistrators_;
- };
-
- template <typename T>
- void PrintAsBytes(const T& obj, IOutputStream& output) {
- const ui8* b = reinterpret_cast<const ui8*>(&obj);
- const ui8* e = b + sizeof(T);
- const char* delim = "";
-
- while (b != e) {
- output << delim;
- output << (int)*b++;
- delim = ".";
- }
- }
-
- template <typename T>
- void PrintAsHex(const T& obj, IOutputStream& output) {
- output << "0x";
- output << HexEncode(&obj, sizeof(T));
- }
-
- inline void PrintAsBase64(TStringBuf data, IOutputStream& output) {
- if (!data.empty()) {
- output << Base64Encode(data);
- }
- }
-
-}
diff --git a/library/cpp/eventlog/iterator.cpp b/library/cpp/eventlog/iterator.cpp
deleted file mode 100644
index 71f955bca8..0000000000
--- a/library/cpp/eventlog/iterator.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "iterator.h"
-
-#include <library/cpp/streams/growing_file_input/growing_file_input.h>
-
-#include <util/string/cast.h>
-#include <util/string/split.h>
-#include <util/string/type.h>
-#include <util/stream/file.h>
-
-using namespace NEventLog;
-
-namespace {
- inline TIntrusivePtr<TEventFilter> ConstructEventFilter(bool enableEvents, const TString& evList, IEventFactory* fac) {
- if (evList.empty()) {
- return nullptr;
- }
-
- TVector<TString> events;
-
- StringSplitter(evList).Split(',').SkipEmpty().Collect(&events);
- if (events.empty()) {
- return nullptr;
- }
-
- TIntrusivePtr<TEventFilter> filter(new TEventFilter(enableEvents));
-
- for (const auto& event : events) {
- if (IsNumber(event))
- filter->AddEventClass(FromString<size_t>(event));
- else
- filter->AddEventClass(fac->ClassByName(event));
- }
-
- return filter;
- }
-
- struct TIterator: public IIterator {
- inline TIterator(const TOptions& o, IEventFactory* fac)
- : First(true)
- {
- if (o.FileName.size()) {
- if (o.ForceStreamMode || o.TailFMode) {
- FileInput.Reset(o.TailFMode ? (IInputStream*)new TGrowingFileInput(o.FileName) : (IInputStream*)new TUnbufferedFileInput(o.FileName));
- FrameStream.Reset(new TFrameStreamer(*FileInput, fac, o.FrameFilter));
- } else {
- FrameStream.Reset(new TFrameStreamer(o.FileName, o.StartTime, o.EndTime, o.MaxRequestDuration, fac, o.FrameFilter));
- }
- } else {
- FrameStream.Reset(new TFrameStreamer(*o.Input, fac, o.FrameFilter));
- }
-
- EvFilter = ConstructEventFilter(o.EnableEvents, o.EvList, fac);
- EventStream.Reset(new TEventStreamer(*FrameStream, o.StartTime, o.EndTime, o.ForceStrongOrdering, EvFilter, o.ForceLosslessStrongOrdering));
- }
-
- TConstEventPtr Next() override {
- if (First) {
- First = false;
-
- if (!EventStream->Avail()) {
- return nullptr;
- }
- } else {
- if (!EventStream->Next()) {
- return nullptr;
- }
- }
-
- return **EventStream;
- }
-
- THolder<IInputStream> FileInput;
- THolder<TFrameStreamer> FrameStream;
- TIntrusivePtr<TEventFilter> EvFilter;
- THolder<TEventStreamer> EventStream;
- bool First;
- };
-}
-
-IIterator::~IIterator() = default;
-
-THolder<IIterator> NEventLog::CreateIterator(const TOptions& o, IEventFactory* fac) {
- return MakeHolder<TIterator>(o, fac);
-}
-
-THolder<IIterator> NEventLog::CreateIterator(const TOptions& o) {
- return MakeHolder<TIterator>(o, NEvClass::Factory());
-}
diff --git a/library/cpp/eventlog/iterator.h b/library/cpp/eventlog/iterator.h
deleted file mode 100644
index 71a61ed549..0000000000
--- a/library/cpp/eventlog/iterator.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#include <util/stream/input.h>
-#include <util/generic/ptr.h>
-#include <util/generic/string.h>
-#include <util/generic/iterator.h>
-
-#include "eventlog.h"
-#include "logparser.h"
-
-namespace NEventLog {
- struct TOptions {
- inline TOptions& SetFileName(const TString& fileName) {
- FileName = fileName;
-
- return *this;
- }
-
- inline TOptions& SetForceStrongOrdering(bool v) {
- if(!ForceLosslessStrongOrdering) {
- ForceStrongOrdering = v;
- }
-
- return *this;
- }
-
- ui64 StartTime = MIN_START_TIME;
- ui64 EndTime = MAX_END_TIME;
- ui64 MaxRequestDuration = MAX_REQUEST_DURATION;
- TString FileName;
- bool ForceStrongOrdering = false;
- bool ForceWeakOrdering = false;
- bool EnableEvents = true;
- TString EvList;
- bool ForceStreamMode = false;
- bool ForceLosslessStrongOrdering = false;
- bool TailFMode = false;
- IInputStream* Input = &Cin;
- IFrameFilterRef FrameFilter;
- };
-
- class IIterator: public TInputRangeAdaptor<IIterator> {
- public:
- virtual ~IIterator();
-
- virtual TConstEventPtr Next() = 0;
- };
-
- THolder<IIterator> CreateIterator(const TOptions& o);
- THolder<IIterator> CreateIterator(const TOptions& o, IEventFactory* fac);
-}
diff --git a/library/cpp/eventlog/logparser.cpp b/library/cpp/eventlog/logparser.cpp
deleted file mode 100644
index 6f8959f788..0000000000
--- a/library/cpp/eventlog/logparser.cpp
+++ /dev/null
@@ -1,814 +0,0 @@
-#include "logparser.h"
-#include "evdecoder.h"
-
-#include <util/stream/output.h>
-#include <util/stream/zlib.h>
-#include <util/digest/murmur.h>
-#include <util/generic/algorithm.h>
-#include <util/generic/scope.h>
-#include <util/generic/hash_set.h>
-#include <util/string/split.h>
-#include <util/string/cast.h>
-#include <util/string/escape.h>
-#include <util/string/builder.h>
-
-#include <contrib/libs/re2/re2/re2.h>
-
-#include <algorithm>
-#include <array>
-
-namespace {
- bool FastforwardUntilSyncHeader(IInputStream* in) {
- // Usually this function finds the correct header at the first hit
- std::array<char, COMPRESSED_LOG_FRAME_SYNC_DATA.size()> buffer;
- if (in->Load(buffer.data(), buffer.size()) != buffer.size()) {
- return false;
- }
-
- auto begin = buffer.begin();
-
- for (;;) {
- if (std::mismatch(
- begin, buffer.end(),
- COMPRESSED_LOG_FRAME_SYNC_DATA.begin()).first == buffer.end() &&
- std::mismatch(
- buffer.begin(), begin,
- COMPRESSED_LOG_FRAME_SYNC_DATA.begin() + (buffer.end() - begin)).first == begin) {
- return true;
- }
- if (!in->ReadChar(*begin)) {
- return false;
- }
- ++begin;
- if (begin == buffer.end()) {
- begin = buffer.begin();
- }
- }
- }
-
- bool HasCorrectChecksum(const TFrameHeader& header) {
- // Calculating hash over all the fields of the read header except for the field with the hash of the header itself.
- const size_t baseSize = sizeof(TCompressedFrameBaseHeader) + sizeof(TCompressedFrameHeader2) - sizeof(ui32);
- const ui32 checksum = MurmurHash<ui32>(&header.Basehdr, baseSize);
- return checksum == header.Framehdr.HeaderChecksum;
- }
-
- TMaybe<TFrameHeader> FindNextFrameHeader(IInputStream* in) {
- for (;;) {
- if (FastforwardUntilSyncHeader(in)) {
- try {
- return TFrameHeader(*in);
- } catch (const TFrameLoadError& err) {
- Cdbg << err.what() << Endl;
- in->Skip(err.SkipAfter);
- }
- } else {
- return Nothing();
- }
- }
- }
-
- std::pair<TMaybe<TFrameHeader>, TStringBuf> FindNextFrameHeader(TStringBuf span) {
- for (;;) {
- auto iter = std::search(
- span.begin(), span.end(),
- COMPRESSED_LOG_FRAME_SYNC_DATA.begin(), COMPRESSED_LOG_FRAME_SYNC_DATA.end());
- const size_t offset = iter - span.begin();
-
- if (offset != span.size()) {
- span = span.substr(offset);
- try {
- TMemoryInput in(
- span.data() + COMPRESSED_LOG_FRAME_SYNC_DATA.size(),
- span.size() - COMPRESSED_LOG_FRAME_SYNC_DATA.size());
- return {TFrameHeader(in), span};
- } catch (const TFrameLoadError& err) {
- Cdbg << err.what() << Endl;
- span = span.substr(err.SkipAfter);
- }
- } else {
- return {Nothing(), {}};
- }
- }
- }
-
- size_t FindFrames(const TStringBuf span, ui64 start, ui64 end, ui64 maxRequestDuration) {
- Y_ENSURE(start <= end);
-
- const auto leftTimeBound = start - Min(start, maxRequestDuration);
- const auto rightTimeBound = end + Min(maxRequestDuration, Max<ui64>() - end);
-
- TStringBuf subspan = span;
- TMaybe<TFrameHeader> maybeLeftFrame;
- std::tie(maybeLeftFrame, subspan) = FindNextFrameHeader(subspan);
-
- if (!maybeLeftFrame || maybeLeftFrame->EndTime() > rightTimeBound) {
- return span.size();
- }
-
- if (maybeLeftFrame->StartTime() > leftTimeBound) {
- return 0;
- }
-
- while (subspan.size() > maybeLeftFrame->FullLength()) {
- const auto mid = subspan.data() + subspan.size() / 2;
- auto [midFrame, rightHalfSpan] = FindNextFrameHeader({mid, subspan.data() + subspan.size()});
- if (!midFrame) {
- // If mid is in the middle of the last frame, here we will lose it meaning that
- // we will find previous frame as the result.
- // This is fine because we will iterate frames starting from that.
- subspan = subspan.substr(0, subspan.size() / 2);
- continue;
- }
- if (midFrame->StartTime() <= leftTimeBound) {
- maybeLeftFrame = midFrame;
- subspan = rightHalfSpan;
- } else {
- subspan = subspan.substr(0, subspan.size() / 2);
- }
- }
-
- return subspan.data() - span.data();
- }
-}
-
-TFrameHeader::TFrameHeader(IInputStream& in) {
- try {
- ::Load(&in, Basehdr);
-
- Y_ENSURE(Basehdr.Length, "Empty frame additional data");
-
- ::Load(&in, Framehdr);
- switch (LogFormat()) {
- case COMPRESSED_LOG_FORMAT_V1:
- break;
-
- case COMPRESSED_LOG_FORMAT_V2:
- case COMPRESSED_LOG_FORMAT_V3:
- case COMPRESSED_LOG_FORMAT_V4:
- case COMPRESSED_LOG_FORMAT_V5:
- Y_ENSURE(!Framehdr.CompressorVersion, "Wrong compressor");
-
- Y_ENSURE(HasCorrectChecksum(*this), "Wrong header checksum");
- break;
-
- default:
- ythrow yexception() << "Unsupported log structure format";
- };
-
- Y_ENSURE(Framehdr.StartTimestamp <= Framehdr.EndTimestamp, "Wrong start/end timestamps");
-
- // Each frame must contain at least one event.
- Y_ENSURE(Framehdr.UncompressedDatalen, "Empty frame payload");
- } catch (...) {
- TString location = "";
- if (const auto* cnt = dynamic_cast<TCountingInput *>(&in)) {
- location = "@ " + ToString(cnt->Counter());
- }
- ythrow TFrameLoadError(FrameLength()) << "Frame Load Error" << location << ": " << CurrentExceptionMessage();
- }
-}
-
-TFrame::TFrame(IInputStream& in, TFrameHeader header, IEventFactory* fac)
- : TFrameHeader(header)
- , Limiter_(MakeHolder<TLengthLimitedInput>(&in, header.FrameLength()))
- , Fac_(fac)
-{
- if (auto* cnt = dynamic_cast<TCountingInput *>(&in)) {
- Address_ = cnt->Counter() - sizeof(TFrameHeader);
- } else {
- Address_ = 0;
- }
-}
-
-TFrame::TIterator TFrame::GetIterator(TIntrusiveConstPtr<TEventFilter> eventFilter) const {
- if (EventsCache_.empty()) {
- for (TFrameDecoder decoder{*this, eventFilter.Get()}; decoder.Avail(); decoder.Next()) {
- EventsCache_.emplace_back(*decoder);
- }
- }
-
- return TIterator(*this, eventFilter);
-}
-
-void TFrame::ClearEventsCache() const {
- EventsCache_.clear();
-}
-
-TString TFrame::GetCompressedFrame() const {
- const auto left = Limiter_->Left();
- TString payload = Limiter_->ReadAll();
- Y_ENSURE(payload.size() == left, "Could not read frame payload: premature end of stream");
- const ui32 checksum = MurmurHash<ui32>(payload.data(), payload.size());
- Y_ENSURE(checksum == Framehdr.PayloadChecksum, "Invalid frame checksum");
-
- return payload;
-}
-
-TString TFrame::GetRawFrame() const {
- TString frameBuf = GetCompressedFrame();
- TStringInput sin(frameBuf);
- return TZLibDecompress{&sin}.ReadAll();
-}
-
-TFrame::TIterator::TIterator(const TFrame& frame, TIntrusiveConstPtr<TEventFilter> filter)
- : Frame_(frame)
- , Size_(frame.EventsCache_.size())
- , Filter_(filter)
- , Index_(0)
-{
- SkipToValidEvent();
-}
-
-TConstEventPtr TFrame::TIterator::operator*() const {
- return Frame_.GetEvent(Index_);
-}
-
-bool TFrame::TIterator::Next() {
- Index_++;
- SkipToValidEvent();
- return Index_ < Size_;
-}
-
-void TFrame::TIterator::SkipToValidEvent() {
- if (!Filter_) {
- return;
- }
-
- for (; Index_ < Size_; ++Index_) {
- if (Filter_->EventAllowed(Frame_.GetEvent(Index_)->Class)) {
- break;
- }
- }
-}
-
-TMaybe<TFrame> FindNextFrame(IInputStream* in, IEventFactory* eventFactory) {
- if (auto header = FindNextFrameHeader(in)) {
- return TFrame{*in, *header, eventFactory};
- } else {
- return Nothing();
- }
-}
-
-TContainsEventFrameFilter::TContainsEventFrameFilter(const TString& unparsedMatchGroups, const IEventFactory* eventFactory) {
- TVector<TStringBuf> tokens;
-
- SplitWithEscaping(tokens, unparsedMatchGroups, "/");
-
- // Amount of match groups
- size_t size = tokens.size();
- MatchGroups.resize(size);
-
- for (size_t i = 0; i < size; i++) {
- TMatchGroup& group = MatchGroups[i];
- TVector<TStringBuf> groupTokens;
- SplitWithEscaping(groupTokens, tokens[i], ":");
-
- Y_ENSURE(groupTokens.size() == 3);
-
- try {
- group.EventID = eventFactory->ClassByName(groupTokens[0]);
- } catch (yexception& e) {
- if (!TryFromString<TEventClass>(groupTokens[0], group.EventID)) {
- e << "\nAppend:\n" << "Cannot derive EventId from EventType: " << groupTokens[0];
- throw e;
- }
- }
-
- group.FieldName = groupTokens[1];
- group.ValueToMatch = UnescapeCharacters(groupTokens[2], "/:");
- }
-}
-
-bool TContainsEventFrameFilter::FrameAllowed(const TFrame& frame) const {
- THashSet<size_t> toMatchSet;
- for (size_t i = 0; i < MatchGroups.size(); i++) {
- toMatchSet.insert(i);
- }
-
- for (auto it = frame.GetIterator(); it.Avail(); it.Next()) {
- TConstEventPtr event(*it);
- TVector<size_t> indicesToErase;
-
- if (!toMatchSet.empty()) {
- const NProtoBuf::Message* message = event->GetProto();
- const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
- const google::protobuf::Reflection* reflection = message->GetReflection();
-
- Y_ENSURE(descriptor);
- Y_ENSURE(reflection);
-
- for (size_t groupIndex : toMatchSet) {
- const TMatchGroup& group = MatchGroups[groupIndex];
-
- if (event->Class == group.EventID) {
- TVector<TString> parts = StringSplitter(group.FieldName).Split('.').ToList<TString>();
- TString lastPart = std::move(parts.back());
- parts.pop_back();
-
- for (auto part : parts) {
- auto fieldDescriptor = descriptor->FindFieldByName(part);
- Y_ENSURE(fieldDescriptor, "Cannot find field \"" + part + "\". Full fieldname is \"" + group.FieldName + "\".");
-
- message = &reflection->GetMessage(*message, fieldDescriptor);
- descriptor = message->GetDescriptor();
- reflection = message->GetReflection();
-
- Y_ENSURE(descriptor);
- Y_ENSURE(reflection);
- }
-
- const google::protobuf::FieldDescriptor* fieldDescriptor = descriptor->FindFieldByName(lastPart);
- Y_ENSURE(fieldDescriptor, "Cannot find field \"" + lastPart + "\". Full fieldname is \"" + group.FieldName + "\".");
-
- TString fieldValue = GetEventFieldAsString(message, fieldDescriptor, reflection);
- if (re2::RE2::FullMatch(fieldValue, group.ValueToMatch)) {
- indicesToErase.push_back(groupIndex);
- }
- }
- }
-
- for (size_t idx : indicesToErase) {
- toMatchSet.erase(idx);
- }
-
- if (toMatchSet.empty()) {
- return true;
- }
- }
- }
-
- return toMatchSet.empty();
-}
-
-void SplitWithEscaping(TVector<TStringBuf>& tokens, const TStringBuf& stringToSplit, const TStringBuf& externalCharacterSet) {
- size_t tokenStart = 0;
- const TString characterSet = TString::Join("\\", externalCharacterSet);
-
- for (size_t position = stringToSplit.find_first_of(characterSet); position != TString::npos; position = stringToSplit.find_first_of(characterSet, position + 1)) {
- if (stringToSplit[position] == '\\') {
- position++;
- } else {
- if (tokenStart != position) {
- tokens.push_back(TStringBuf(stringToSplit, tokenStart, position - tokenStart));
- }
- tokenStart = position + 1;
- }
- }
-
- if (tokenStart < stringToSplit.size()) {
- tokens.push_back(TStringBuf(stringToSplit, tokenStart, stringToSplit.size() - tokenStart));
- }
-}
-
-TString UnescapeCharacters(const TStringBuf& stringToUnescape, const TStringBuf& characterSet) {
- TStringBuilder stringBuilder;
- size_t tokenStart = 0;
-
- for (size_t position = stringToUnescape.find('\\', 0u); position != TString::npos; position = stringToUnescape.find('\\', position + 2)) {
- if (position + 1 < stringToUnescape.size() && characterSet.find(stringToUnescape[position + 1]) != TString::npos) {
- stringBuilder << TStringBuf(stringToUnescape, tokenStart, position - tokenStart);
- tokenStart = position + 1;
- }
- }
-
- if (tokenStart < stringToUnescape.size()) {
- stringBuilder << TStringBuf(stringToUnescape, tokenStart, stringToUnescape.size() - tokenStart);
- }
-
- return stringBuilder;
-}
-
-TString GetEventFieldAsString(const NProtoBuf::Message* message, const google::protobuf::FieldDescriptor* fieldDescriptor, const google::protobuf::Reflection* reflection) {
- Y_ENSURE(message);
- Y_ENSURE(fieldDescriptor);
- Y_ENSURE(reflection);
-
- TString result;
- switch (fieldDescriptor->type()) {
- case google::protobuf::FieldDescriptor::Type::TYPE_DOUBLE:
- result = ToString(reflection->GetDouble(*message, fieldDescriptor));
- break;
- case google::protobuf::FieldDescriptor::Type::TYPE_FLOAT:
- result = ToString(reflection->GetFloat(*message, fieldDescriptor));
- break;
- case google::protobuf::FieldDescriptor::Type::TYPE_BOOL:
- result = ToString(reflection->GetBool(*message, fieldDescriptor));
- break;
- case google::protobuf::FieldDescriptor::Type::TYPE_INT32:
- result = ToString(reflection->GetInt32(*message, fieldDescriptor));
- break;
- case google::protobuf::FieldDescriptor::Type::TYPE_UINT32:
- result = ToString(reflection->GetUInt32(*message, fieldDescriptor));
- break;
- case google::protobuf::FieldDescriptor::Type::TYPE_INT64:
- result = ToString(reflection->GetInt64(*message, fieldDescriptor));
- break;
- case google::protobuf::FieldDescriptor::Type::TYPE_UINT64:
- result = ToString(reflection->GetUInt64(*message, fieldDescriptor));
- break;
- case google::protobuf::FieldDescriptor::Type::TYPE_STRING:
- result = ToString(reflection->GetString(*message, fieldDescriptor));
- break;
- case google::protobuf::FieldDescriptor::Type::TYPE_ENUM:
- {
- const NProtoBuf::EnumValueDescriptor* enumValueDescriptor = reflection->GetEnum(*message, fieldDescriptor);
- result = ToString(enumValueDescriptor->name());
- }
- break;
- default:
- throw yexception() << "GetEventFieldAsString for type " << fieldDescriptor->type_name() << " is not implemented.";
- }
- return result;
-}
-
-TFrameStreamer::TFrameStreamer(IInputStream& s, IEventFactory* fac, IFrameFilterRef ff)
- : In_(&s)
- , FrameFilter_(ff)
- , EventFactory_(fac)
-{
- Frame_ = FindNextFrame(&In_, EventFactory_);
-
- SkipToAllowedFrame();
-}
-
-TFrameStreamer::TFrameStreamer(
- const TString& fileName,
- ui64 startTime,
- ui64 endTime,
- ui64 maxRequestDuration,
- IEventFactory* fac,
- IFrameFilterRef ff)
- : File_(TBlob::FromFile(fileName))
- , MemoryIn_(File_.Data(), File_.Size())
- , In_(&MemoryIn_)
- , StartTime_(startTime)
- , EndTime_(endTime)
- , CutoffTime_(endTime + Min(maxRequestDuration, Max<ui64>() - endTime))
- , FrameFilter_(ff)
- , EventFactory_(fac)
-{
- In_.Skip(FindFrames(File_.AsStringBuf(), startTime, endTime, maxRequestDuration));
- Frame_ = FindNextFrame(&In_, fac);
- SkipToAllowedFrame();
-}
-
-TFrameStreamer::~TFrameStreamer() = default;
-
-bool TFrameStreamer::Avail() const {
- return Frame_.Defined();
-}
-
-const TFrame& TFrameStreamer::operator*() const {
- Y_ENSURE(Frame_, "Frame streamer depleted");
-
- return *Frame_;
-}
-
-bool TFrameStreamer::Next() {
- DoNext();
- SkipToAllowedFrame();
-
- return Frame_.Defined();
-}
-
-bool TFrameStreamer::AllowedTimeRange(const TFrame& frame) const {
- const bool allowedStartTime = (StartTime_ == 0) || ((StartTime_ <= frame.StartTime()) && (frame.StartTime() <= EndTime_));
- const bool allowedEndTime = (EndTime_ == 0) || ((StartTime_ <= frame.EndTime()) && (frame.EndTime() <= EndTime_));
- return allowedStartTime || allowedEndTime;
-}
-
-bool TFrameStreamer::DoNext() {
- if (!Frame_) {
- return false;
- }
- In_.Skip(Frame_->Limiter_->Left());
- Frame_ = FindNextFrame(&In_, EventFactory_);
-
- if (Frame_ && CutoffTime_ > 0 && Frame_->EndTime() > CutoffTime_) {
- Frame_.Clear();
- }
-
- return Frame_.Defined();
-}
-
-namespace {
- struct TDecodeBuffer {
- TDecodeBuffer(const TString codec, IInputStream& src, size_t bs) {
- TBuffer from(bs);
-
- {
- TBufferOutput b(from);
- TransferData(&src, &b);
- }
-
- NBlockCodecs::Codec(codec)->Decode(from, DecodeBuffer);
- }
-
- explicit TDecodeBuffer(IInputStream& src) {
- TBufferOutput b(DecodeBuffer);
- TransferData(&src, &b);
- }
-
- TBuffer DecodeBuffer;
- };
-
- class TBlockCodecStream: private TDecodeBuffer, public TBufferInput {
- public:
- TBlockCodecStream(const TString codec, IInputStream& src, size_t bs)
- : TDecodeBuffer(codec, src, bs)
- , TBufferInput(DecodeBuffer)
- {}
-
- explicit TBlockCodecStream(IInputStream& src)
- : TDecodeBuffer(src)
- , TBufferInput(DecodeBuffer)
- {}
- };
-}
-
-TFrameDecoder::TFrameDecoder(const TFrame& fr, const TEventFilter* const filter, bool strict, bool withRawData)
- : Frame_(fr)
- , Event_(nullptr)
- , Flt_(filter)
- , Fac_(fr.Fac_)
- , EndOfFrame_(new TEndOfFrameEvent(Frame_.EndTime()))
- , Strict_(strict)
- , WithRawData_(withRawData)
-{
- switch (fr.LogFormat()) {
- case COMPRESSED_LOG_FORMAT_V2:
- case COMPRESSED_LOG_FORMAT_V3:
- case COMPRESSED_LOG_FORMAT_V4:
- case COMPRESSED_LOG_FORMAT_V5: {
- const auto payload = fr.GetCompressedFrame();
- TMemoryInput payloadInput{payload};
-
- if (fr.LogFormat() == COMPRESSED_LOG_FORMAT_V5) {
- Decompressor_.Reset(new TBlockCodecStream("zstd_1", payloadInput, payload.size()));
- } else {
- TZLibDecompress zlib(&payloadInput);
- Decompressor_.Reset(new TBlockCodecStream(zlib));
- if (fr.LogFormat() == COMPRESSED_LOG_FORMAT_V4) {
- Decompressor_.Reset(new TBlockCodecStream("lz4hc", *Decompressor_, payload.size()));
- }
- }
-
- break;
- }
-
- default:
- ythrow yexception() << "unsupported log format: " << fr.LogFormat() << Endl;
- break;
- };
-
- if (WithRawData_) {
- TBufferOutput out(UncompressedData_);
- TLengthLimitedInput limiter(Decompressor_.Get(), fr.Framehdr.UncompressedDatalen);
-
- TransferData(&limiter, &out);
- Decompressor_.Reset(new TMemoryInput(UncompressedData_.data(), UncompressedData_.size()));
- }
-
- Limiter_.Reset(new TLengthLimitedInput(Decompressor_.Get(), fr.Framehdr.UncompressedDatalen));
-
- Decode();
-}
-
-TFrameDecoder::~TFrameDecoder() = default;
-
-bool TFrameDecoder::Avail() const {
- return HaveData();
-}
-
-TConstEventPtr TFrameDecoder::operator*() const {
- Y_ENSURE(HaveData(), "Decoder depleted");
-
- return Event_;
-}
-
-bool TFrameDecoder::Next() {
- if (HaveData()) {
- Decode();
- }
-
- return HaveData();
-}
-
-void TFrameDecoder::Decode() {
- Event_ = nullptr;
- const bool framed = (Frame_.LogFormat() == COMPRESSED_LOG_FORMAT_V3) || (Frame_.LogFormat() == COMPRESSED_LOG_FORMAT_V4 || Frame_.LogFormat() == COMPRESSED_LOG_FORMAT_V5);
-
- size_t evBegin = 0;
- size_t evEnd = 0;
- if (WithRawData_)
- evBegin = UncompressedData_.Size() - Limiter_->Left();
-
- while (Limiter_->Left() && !(Event_ = DecodeEvent(*Limiter_, framed, Frame_.Address(), Flt_, Fac_, Strict_).Release())) {
- }
-
- if (WithRawData_) {
- evEnd = UncompressedData_.Size() - Limiter_->Left();
- RawEventData_ = TStringBuf(UncompressedData_.data() + evBegin, UncompressedData_.data() + evEnd);
- }
-
- if (!Event_ && (!Flt_ || (Flt_->EventAllowed(TEndOfFrameEvent::EventClass)))) {
- Event_ = EndOfFrame_.Release();
- }
-
- if (!!Event_) {
- Event_->FrameId = Frame_.FrameId();
- }
-}
-
-const TStringBuf TFrameDecoder::GetRawEvent() const {
- return RawEventData_;
-}
-
-TEventStreamer::TEventStreamer(TFrameStream& fs, ui64 s, ui64 e, bool strongOrdering, TIntrusivePtr<TEventFilter> filter, bool losslessStrongOrdering)
- : Frames_(fs)
- , Start_(s)
- , End_(e)
- , MaxEndTimestamp_(0)
- , Frontier_(0)
- , StrongOrdering_(strongOrdering)
- , LosslessStrongOrdering_(losslessStrongOrdering)
- , EventFilter_(filter)
-{
-
- if (Start_ > End_) {
- ythrow yexception() << "Wrong main interval";
- }
-
- TEventStreamer::Next();
-}
-
-TEventStreamer::~TEventStreamer() = default;
-
-bool TEventStreamer::Avail() const {
- return Events_.Avail() && (*Events_)->Timestamp <= Frontier_;
-}
-
-TConstEventPtr TEventStreamer::operator*() const {
- Y_ENSURE(TEventStreamer::Avail(), "Event streamer depleted");
-
- return *Events_;
-}
-
-bool TEventStreamer::Next() {
- if (Events_.Avail() && Events_.Next() && (*Events_)->Timestamp <= Frontier_) {
- return true;
- }
-
- for (;;) {
- if (!LoadMoreEvents()) {
- return false;
- }
-
- if (TEventStreamer::Avail()) {
- return true;
- }
- }
-}
-
-/*
-Two parameters are used in the function:
-Frontier - the moment of time up to which inclusively all the log events made their way
- into the buffer (and might have been already extracted out of it).
-Horizon - the moment of time, that equals to Frontier + MAX_REQUEST_DURATION.
-In order to get all the log events up to the Frontier inclusively,
- frames need to be read until "end time" of the current frame exceeds the Horizon.
-*/
-bool TEventStreamer::LoadMoreEvents() {
- if (!Frames_.Avail()) {
- return false;
- }
-
- const TFrame& fr1 = *Frames_;
- const ui64 maxRequestDuration = (StrongOrdering_ ? MAX_REQUEST_DURATION : 0);
-
- if (fr1.EndTime() <= Frontier_ + maxRequestDuration) {
- ythrow yexception() << "Wrong frame stream state";
- }
-
- if (Frontier_ >= End_) {
- return false;
- }
-
- const ui64 old_frontier = Frontier_;
- Frontier_ = fr1.EndTime();
-
- {
- Y_DEFER {
- Events_.Reorder(StrongOrdering_);
- };
-
- for (; Frames_.Avail(); Frames_.Next()) {
- const TFrame& fr2 = *Frames_;
-
- // Frames need to start later than the Frontier.
- if (StrongOrdering_ && fr2.StartTime() <= old_frontier) {
- Cdbg << "Invalid frame encountered" << Endl;
- continue;
- }
-
- if (fr2.EndTime() > MaxEndTimestamp_) {
- MaxEndTimestamp_ = fr2.EndTime();
- }
-
- if (fr2.EndTime() > Frontier_ + maxRequestDuration && !LosslessStrongOrdering_) {
- return true;
- }
-
- // Checking for the frame to be within the main time borders.
- if (fr2.EndTime() >= Start_ && fr2.StartTime() <= End_) {
- TransferEvents(fr2);
- }
- }
- }
-
- Frontier_ = MaxEndTimestamp_;
-
- return true;
-}
-
-void TEventStreamer::TransferEvents(const TFrame& fr) {
- Events_.SetCheckpoint();
-
- try {
- for (auto it = fr.GetIterator(EventFilter_); it.Avail(); it.Next()) {
- TConstEventPtr ev = *it;
-
- if (ev->Timestamp > fr.EndTime() || ev->Timestamp < fr.StartTime()) {
- ythrow TInvalidEventTimestamps() << "Event timestamp out of frame range";
- }
-
- if (ev->Timestamp >= Start_ && ev->Timestamp <= End_) {
- Events_.Append(ev, StrongOrdering_);
- }
- }
- } catch (const TInvalidEventTimestamps& err) {
- Events_.Rollback();
- Cdbg << "EventsTransfer error: InvalidEventTimestamps: " << err.what() << Endl;
- } catch (const TFrameLoadError& err) {
- Events_.Rollback();
- Cdbg << "EventsTransfer error: " << err.what() << Endl;
- } catch (const TEventDecoderError& err) {
- Events_.Rollback();
- Cdbg << "EventsTransfer error: EventDecoder error: " << err.what() << Endl;
- } catch (const TZLibDecompressorError& err) {
- Events_.Rollback();
- Cdbg << "EventsTransfer error: ZLibDecompressor error: " << err.what() << Endl;
- } catch (...) {
- Events_.Rollback();
- throw;
- }
-}
-
-void TEventStreamer::TEventBuffer::SetCheckpoint() {
- BufLen_ = Buffer_.size();
-}
-
-void TEventStreamer::TEventBuffer::Rollback() {
- Buffer_.resize(BufLen_);
-}
-
-void TEventStreamer::TEventBuffer::Reorder(bool strongOrdering) {
- SetCheckpoint();
-
- std::reverse(Buffer_.begin(), Buffer_.end());
-
- if (strongOrdering) {
- StableSort(Buffer_.begin(), Buffer_.end(), [&](const auto& a, const auto& b) {
- return (a->Timestamp > b->Timestamp) ||
- ((a->Timestamp == b->Timestamp) && !a->Class && b->Class);
- });
- }
-}
-
-void TEventStreamer::TEventBuffer::Append(TConstEventPtr ev, bool strongOrdering) {
- // Events in buffer output must be in an ascending order.
- Y_ENSURE(!strongOrdering || ev->Timestamp >= LastTimestamp_, "Trying to append out-of-order event");
-
- Buffer_.push_back(std::move(ev));
-}
-
-bool TEventStreamer::TEventBuffer::Avail() const {
- return !Buffer_.empty();
-}
-
-TConstEventPtr TEventStreamer::TEventBuffer::operator*() const {
- Y_ENSURE(!Buffer_.empty(), "Event buffer is empty");
-
- return Buffer_.back();
-}
-
-bool TEventStreamer::TEventBuffer::Next() {
- if (!Buffer_.empty()) {
- LastTimestamp_ = Buffer_.back()->Timestamp;
- Buffer_.pop_back();
- return !Buffer_.empty();
- } else {
- return false;
- }
-}
diff --git a/library/cpp/eventlog/logparser.h b/library/cpp/eventlog/logparser.h
deleted file mode 100644
index f819e72589..0000000000
--- a/library/cpp/eventlog/logparser.h
+++ /dev/null
@@ -1,343 +0,0 @@
-#pragma once
-
-#include <util/generic/ptr.h>
-#include <util/generic/yexception.h>
-#include <util/generic/vector.h>
-#include <util/generic/set.h>
-#include <util/generic/maybe.h>
-#include <util/memory/blob.h>
-#include <util/stream/length.h>
-#include <util/stream/mem.h>
-
-#include "eventlog_int.h"
-#include "eventlog.h"
-#include "common.h"
-
-class IInputStream;
-
-static const ui64 MAX_REQUEST_DURATION = 60'000'000;
-static const ui64 MIN_START_TIME = MAX_REQUEST_DURATION;
-static const ui64 MAX_END_TIME = ((ui64)-1) - MAX_REQUEST_DURATION;
-
-class TEventFilter: public TSet<TEventClass>, public TSimpleRefCount<TEventFilter> {
-public:
- TEventFilter(bool enableEvents)
- : Enable_(enableEvents)
- {
- }
-
- void AddEventClass(TEventClass cls) {
- insert(cls);
- }
-
- bool EventAllowed(TEventClass cls) const {
- bool found = (find(cls) != end());
-
- return Enable_ == found;
- }
-
-private:
- bool Enable_;
-};
-
-using TEventStream = TPacketInputStream<TConstEventPtr>;
-
-struct TFrameHeader {
- // Reads header from the stream. The caller must make sure that the
- // sync data is present just befor the stream position.
- explicit TFrameHeader(IInputStream& in);
-
- ui64 StartTime() const {
- return Framehdr.StartTimestamp;
- }
-
- ui64 EndTime() const {
- return Framehdr.EndTimestamp;
- }
-
- ui32 FrameId() const {
- return Basehdr.FrameId;
- }
-
- ui64 Duration() const {
- return EndTime() - StartTime();
- }
-
- TEventLogFormat ContentFormat() const {
- return Basehdr.Format & 0xffffff;
- }
-
- TEventLogFormat LogFormat() const {
- return Basehdr.Format >> 24;
- }
-
- ui64 FrameLength() const {
- return Basehdr.Length - sizeof(TCompressedFrameHeader2);
- }
-
- // Length including the header
- ui64 FullLength() const {
- return sizeof(*this) + FrameLength();
- }
-
- TCompressedFrameBaseHeader Basehdr;
- TCompressedFrameHeader2 Framehdr;
-};
-
-struct TFrameLoadError: public yexception {
- explicit TFrameLoadError(size_t skipAfter)
- : SkipAfter(skipAfter)
- {}
-
- size_t SkipAfter;
-};
-
-class TFrame : public TFrameHeader {
-public:
- // Reads the frame after the header has been read.
- TFrame(IInputStream& in, TFrameHeader header, IEventFactory*);
-
- TString GetRawFrame() const;
- TString GetCompressedFrame() const;
-
- ui64 Address() const { return Address_; }
-
-private:
- const TConstEventPtr& GetEvent(size_t index) const {
- return EventsCache_[index];
- }
-
- void ClearEventsCache() const;
-
- THolder<TLengthLimitedInput> Limiter_;
- mutable TVector<TConstEventPtr> EventsCache_;
-
- IEventFactory* Fac_;
- ui64 Address_;
-
- friend class TFrameDecoder;
- friend class TFrameStreamer;
-
-private:
- class TIterator: TEventStream {
- public:
- TIterator(const TFrame& frame, TIntrusiveConstPtr<TEventFilter> filter);
- ~TIterator() override = default;
-
- bool Avail() const override {
- return Index_ < Size_;
- }
-
- TConstEventPtr operator*() const override;
- bool Next() override;
-
- private:
- void SkipToValidEvent();
-
- const TFrame& Frame_;
- size_t Size_;
- TIntrusiveConstPtr<TEventFilter> Filter_;
- size_t Index_;
- };
-
-public:
- TFrame::TIterator GetIterator(TIntrusiveConstPtr<TEventFilter> eventFilter = nullptr) const;
-};
-
-// If `in` is derived from TCountingInput, Frame's address will
-// be set accorting to the in->Counter(). Otherwise it will be zeroO
-TMaybe<TFrame> FindNextFrame(IInputStream* in, IEventFactory*);
-
-using TFrameStream = TPacketInputStream<const TFrame&>;
-
-class IFrameFilter: public TSimpleRefCount<IFrameFilter> {
-public:
- IFrameFilter() {
- }
-
- virtual ~IFrameFilter() = default;
-
- virtual bool FrameAllowed(const TFrame& frame) const = 0;
-};
-
-using IFrameFilterRef = TIntrusivePtr<IFrameFilter>;
-
-class TDurationFrameFilter: public IFrameFilter {
-public:
- TDurationFrameFilter(ui64 minFrameDuration, ui64 maxFrameDuration = Max<ui64>())
- : MinDuration_(minFrameDuration)
- , MaxDuration_(maxFrameDuration)
- {
- }
-
- bool FrameAllowed(const TFrame& frame) const override {
- return frame.Duration() >= MinDuration_ && frame.Duration() <= MaxDuration_;
- }
-
-private:
- const ui64 MinDuration_;
- const ui64 MaxDuration_;
-};
-
-class TFrameIdFrameFilter: public IFrameFilter {
-public:
- TFrameIdFrameFilter(ui32 frameId)
- : FrameId_(frameId)
- {
- }
-
- bool FrameAllowed(const TFrame& frame) const override {
- return frame.FrameId() == FrameId_;
- }
-
-private:
- const ui32 FrameId_;
-};
-
-class TContainsEventFrameFilter: public IFrameFilter {
-public:
- TContainsEventFrameFilter(const TString& args, const IEventFactory* fac);
-
- bool FrameAllowed(const TFrame& frame) const override;
-
-private:
- struct TMatchGroup {
- TEventClass EventID;
- TString FieldName;
- TString ValueToMatch;
- };
-
- TVector<TMatchGroup> MatchGroups;
-};
-
-void SplitWithEscaping(TVector<TStringBuf>& tokens, const TStringBuf& stringToSplit, const TStringBuf& externalCharacterSet);
-
-TString UnescapeCharacters(const TStringBuf& stringToUnescape, const TStringBuf& characterSet);
-
-TString GetEventFieldAsString(const NProtoBuf::Message* message, const google::protobuf::FieldDescriptor* fieldDescriptor, const google::protobuf::Reflection* reflection);
-
-class TFrameStreamer: public TFrameStream {
-public:
- TFrameStreamer(IInputStream&, IEventFactory* fac, IFrameFilterRef ff = nullptr);
- TFrameStreamer(
- const TString& fileName,
- ui64 startTime,
- ui64 endTime,
- ui64 maxRequestDuration,
- IEventFactory* fac,
- IFrameFilterRef ff = nullptr);
- ~TFrameStreamer() override;
-
- bool Avail() const override;
- const TFrame& operator*() const override;
- bool Next() override;
-
-private:
- bool DoNext();
- bool AllowedTimeRange(const TFrame& frame) const;
-
- bool AllowedFrame(const TFrame& frame) const {
- return AllowedTimeRange(frame) && (!FrameFilter_ || FrameFilter_->FrameAllowed(frame));
- }
-
- void SkipToAllowedFrame() {
- if (Frame_) {
- while (!AllowedFrame(*Frame_) && DoNext()) {
- //do nothing
- }
- }
- }
-
- TBlob File_;
- TMemoryInput MemoryIn_;
- TCountingInput In_;
- THolder<IInputStream> Stream_;
- ui64 StartTime_ = 0;
- ui64 EndTime_ = 0;
- ui64 CutoffTime_ = 0;
- TMaybe<TFrame> Frame_;
- IFrameFilterRef FrameFilter_;
- IEventFactory* EventFactory_;
-};
-
-class TFrameDecoder: TEventStream {
-public:
- TFrameDecoder(const TFrame&, const TEventFilter* const filter, bool strict = false, bool withRawData = false);
- ~TFrameDecoder() override;
-
- bool Avail() const override;
-
- TConstEventPtr operator*() const override;
- bool Next() override;
-
- const TStringBuf GetRawEvent() const;
-
-private:
- TFrameDecoder(const TFrameDecoder&);
- void operator=(const TFrameDecoder&);
-
- inline bool HaveData() const {
- return Event_ != nullptr;
- }
-
- void Decode();
-
-private:
- const TFrame& Frame_;
- THolder<IInputStream> Decompressor_;
- THolder<TLengthLimitedInput> Limiter_;
- TEventPtr Event_;
- const TEventFilter* const Flt_;
- IEventFactory* Fac_;
- THolder<TEvent> EndOfFrame_;
- bool Strict_;
- TBuffer UncompressedData_;
- TStringBuf RawEventData_;
- bool WithRawData_;
-};
-
-class TEventStreamer: public TEventStream {
-public:
- TEventStreamer(TFrameStream&, ui64 start, ui64 end, bool strongOrdering, TIntrusivePtr<TEventFilter> filter, bool losslessStrongOrdering = false);
- ~TEventStreamer() override;
-
- bool Avail() const override;
- TConstEventPtr operator*() const override;
- bool Next() override;
-
-private:
- class TEventBuffer: public TEventStream {
- public:
- void SetCheckpoint();
- void Rollback();
- void Reorder(bool strongOrdering);
- void Append(TConstEventPtr event, bool strongOrdering);
-
- bool Avail() const override;
- TConstEventPtr operator*() const override;
- bool Next() override;
-
- private:
- TVector<TConstEventPtr> Buffer_;
- size_t BufLen_ = 0;
- ui64 LastTimestamp_ = 0;
- };
-
-private:
- struct TInvalidEventTimestamps: public yexception {
- };
-
- bool LoadMoreEvents();
- void TransferEvents(const TFrame&);
-
-private:
- TFrameStream& Frames_;
- TEventBuffer Events_;
-
- ui64 Start_, End_;
- ui64 MaxEndTimestamp_;
- ui64 Frontier_;
- bool StrongOrdering_;
- bool LosslessStrongOrdering_;
- TIntrusivePtr<TEventFilter> EventFilter_;
-};
diff --git a/library/cpp/eventlog/proto/events_extension.proto b/library/cpp/eventlog/proto/events_extension.proto
deleted file mode 100644
index 7db1af3a59..0000000000
--- a/library/cpp/eventlog/proto/events_extension.proto
+++ /dev/null
@@ -1,22 +0,0 @@
-import "google/protobuf/descriptor.proto";
-
-option go_package = "github.com/ydb-platform/ydb/library/cpp/eventlog/proto;extensions";
-option java_package = "NEventLogEventsExtension";
-
-extend google.protobuf.MessageOptions {
- optional uint32 message_id = 50001;
- optional string realm_name = 50002;
-}
-
-message Repr {
- enum ReprType {
- none = 0;
- as_bytes = 1; // Only for primitive types
- as_hex = 2; // Only for primitive types
- as_base64 = 3; // Only for 'string' and 'bytes' fields
- };
-}
-
-extend google.protobuf.FieldOptions {
- optional Repr.ReprType repr = 55003 [default = none];
-}
diff --git a/library/cpp/eventlog/proto/internal.proto b/library/cpp/eventlog/proto/internal.proto
deleted file mode 100644
index 8070a09685..0000000000
--- a/library/cpp/eventlog/proto/internal.proto
+++ /dev/null
@@ -1,9 +0,0 @@
-option go_package = "github.com/ydb-platform/ydb/library/cpp/eventlog/proto;extensions";
-
-package NEventLogInternal;
-
-message TUnknownEvent {
-};
-
-message TEndOfFrameEvent {
-};
diff --git a/library/cpp/eventlog/proto/ya.make b/library/cpp/eventlog/proto/ya.make
deleted file mode 100644
index fbf5a6c619..0000000000
--- a/library/cpp/eventlog/proto/ya.make
+++ /dev/null
@@ -1,12 +0,0 @@
-PROTO_LIBRARY()
-
-IF (NOT PY_PROTOS_FOR)
- INCLUDE_TAGS(GO_PROTO)
-ENDIF()
-
-SRCS(
- events_extension.proto
- internal.proto
-)
-
-END()
diff --git a/library/cpp/eventlog/threaded_eventlog.cpp b/library/cpp/eventlog/threaded_eventlog.cpp
deleted file mode 100644
index 67839063fb..0000000000
--- a/library/cpp/eventlog/threaded_eventlog.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "threaded_eventlog.h"
diff --git a/library/cpp/eventlog/threaded_eventlog.h b/library/cpp/eventlog/threaded_eventlog.h
deleted file mode 100644
index 52382b856d..0000000000
--- a/library/cpp/eventlog/threaded_eventlog.h
+++ /dev/null
@@ -1,154 +0,0 @@
-#pragma once
-
-#include "eventlog.h"
-
-#include <util/generic/string.h>
-#include <util/thread/pool.h>
-
-class TThreadedEventLog: public TEventLogWithSlave {
-public:
- class TWrapper;
- using TOverflowCallback = std::function<void(TWrapper& wrapper)>;
-
- enum class EDegradationResult {
- ShouldWrite,
- ShouldDrop,
- };
- using TDegradationCallback = std::function<EDegradationResult(float fillFactor)>;
-
-public:
- TThreadedEventLog(
- IEventLog& parentLog,
- size_t threadCount,
- size_t queueSize,
- TOverflowCallback cb,
- TDegradationCallback degradationCallback = {})
- : TEventLogWithSlave(parentLog)
- , LogSaver(TThreadPoolParams().SetThreadName("ThreadedEventLog"))
- , ThreadCount(threadCount)
- , QueueSize(queueSize)
- , OverflowCallback(std::move(cb))
- , DegradationCallback(std::move(degradationCallback))
- {
- Init();
- }
-
- TThreadedEventLog(
- const TEventLogPtr& parentLog,
- size_t threadCount,
- size_t queueSize,
- TOverflowCallback cb,
- TDegradationCallback degradationCallback = {})
- : TEventLogWithSlave(parentLog)
- , LogSaver(TThreadPoolParams().SetThreadName("ThreadedEventLog"))
- , ThreadCount(threadCount)
- , QueueSize(queueSize)
- , OverflowCallback(std::move(cb))
- , DegradationCallback(std::move(degradationCallback))
- {
- Init();
- }
-
- TThreadedEventLog(IEventLog& parentLog)
- : TThreadedEventLog(parentLog, 1, 0, TOverflowCallback())
- {
- }
-
- TThreadedEventLog(const TEventLogPtr& parentLog)
- : TThreadedEventLog(parentLog, 1, 0, TOverflowCallback())
- {
- }
-
- ~TThreadedEventLog() override {
- try {
- LogSaver.Stop();
- } catch (...) {
- }
- }
-
- void ReopenLog() override {
- TEventLogWithSlave::ReopenLog();
- }
-
- void CloseLog() override {
- LogSaver.Stop();
- TEventLogWithSlave::CloseLog();
- }
-
- void WriteFrame(TBuffer& buffer,
- TEventTimestamp startTimestamp,
- TEventTimestamp endTimestamp,
- TWriteFrameCallbackPtr writeFrameCallback = nullptr,
- TLogRecord::TMetaFlags metaFlags = {}) override {
- float fillFactor = 0.0f;
- if (Y_LIKELY(LogSaver.GetMaxQueueSize() > 0)) {
- fillFactor = static_cast<float>(LogSaver.Size()) / LogSaver.GetMaxQueueSize();
- }
-
- EDegradationResult status = EDegradationResult::ShouldWrite;
- if (DegradationCallback) {
- status = DegradationCallback(fillFactor);
- }
- if (Y_UNLIKELY(status == EDegradationResult::ShouldDrop)) {
- return;
- }
-
- THolder<TWrapper> wrapped;
- wrapped.Reset(new TWrapper(buffer, startTimestamp, endTimestamp, Slave(), writeFrameCallback, std::move(metaFlags)));
-
- if (LogSaver.Add(wrapped.Get())) {
- Y_UNUSED(wrapped.Release());
- } else if (OverflowCallback) {
- OverflowCallback(*wrapped);
- }
- }
-
-private:
- void Init() {
- LogSaver.Start(ThreadCount, QueueSize);
- }
-
-public:
- class TWrapper: public IObjectInQueue {
- public:
- TWrapper(TBuffer& buffer,
- TEventTimestamp startTimestamp,
- TEventTimestamp endTimestamp,
- IEventLog& slave,
- TWriteFrameCallbackPtr writeFrameCallback = nullptr,
- TLogRecord::TMetaFlags metaFlags = {})
- : StartTimestamp(startTimestamp)
- , EndTimestamp(endTimestamp)
- , Slave(&slave)
- , WriteFrameCallback(writeFrameCallback)
- , MetaFlags(std::move(metaFlags))
- {
- Buffer.Swap(buffer);
- }
-
- void Process(void*) override {
- THolder<TWrapper> holder(this);
-
- WriteFrame();
- }
-
- void WriteFrame() {
- Slave->WriteFrame(Buffer, StartTimestamp, EndTimestamp, WriteFrameCallback, std::move(MetaFlags));
- }
-
- private:
- TBuffer Buffer;
- TEventTimestamp StartTimestamp;
- TEventTimestamp EndTimestamp;
- IEventLog* Slave;
- TWriteFrameCallbackPtr WriteFrameCallback;
- TLogRecord::TMetaFlags MetaFlags;
- };
-
-private:
- TThreadPool LogSaver;
- const size_t ThreadCount;
- const size_t QueueSize;
- const TOverflowCallback OverflowCallback;
- const TDegradationCallback DegradationCallback;
-};
diff --git a/library/cpp/eventlog/ya.make b/library/cpp/eventlog/ya.make
deleted file mode 100644
index fbbc1eff00..0000000000
--- a/library/cpp/eventlog/ya.make
+++ /dev/null
@@ -1,29 +0,0 @@
-LIBRARY()
-
-PEERDIR(
- library/cpp/blockcodecs
- library/cpp/eventlog/proto
- library/cpp/json
- library/cpp/logger
- library/cpp/protobuf/json
- library/cpp/streams/growing_file_input
- library/cpp/string_utils/base64
- contrib/libs/re2
-)
-
-SRCS(
- common.h
- evdecoder.cpp
- event_field_output.cpp
- event_field_printer.cpp
- eventlog.cpp
- eventlog_int.cpp
- iterator.cpp
- logparser.cpp
- threaded_eventlog.cpp
-)
-
-GENERATE_ENUM_SERIALIZATION(eventlog.h)
-GENERATE_ENUM_SERIALIZATION(eventlog_int.h)
-
-END()
diff --git a/library/cpp/fieldcalc/field_calc.cpp b/library/cpp/fieldcalc/field_calc.cpp
deleted file mode 100644
index 1066b5b5e6..0000000000
--- a/library/cpp/fieldcalc/field_calc.cpp
+++ /dev/null
@@ -1,1136 +0,0 @@
-#include <cstdio>
-
-#include <util/str_stl.h>
-#include <util/string/subst.h>
-#include <util/string/util.h>
-#include <util/string/cast.h>
-#include <util/stream/printf.h>
-
-#include "field_calc_int.h"
-
-using namespace std;
-
-enum Operators {
- OP_ADD,
- OP_SUBSTRACT,
- OP_MULTIPLY,
- OP_DIVIDE,
- OP_MODULUS,
- OP_REGEXP,
- OP_REGEXP_NOT,
- OP_LEFT_SHIFT,
- OP_RIGHT_SHIFT,
- OP_EQUAL,
- OP_NOT_EQUAL,
- OP_LESS,
- OP_LESS_OR_EQUAL,
- OP_GREATER,
- OP_GREATER_OR_EQUAL,
- OP_XOR,
- OP_BITWISE_OR,
- OP_BITWISE_AND,
- OP_LOGICAL_OR,
- OP_LOGICAL_AND,
- OP_UNARY_NOT,
- OP_UNARY_COMPLEMENT,
- OP_UNARY_MINUS,
- OP_LOG,
- OP_LOG10,
- OP_ROUND,
- OP_ASSIGN,
- OP_QUESTION,
- OP_COLON,
-
- OP_UNKNOWN,
-};
-
-struct calc_op;
-
-struct calc_elem {
- dump_item item;
- char oper;
- int op_prio;
-};
-
-struct calc_op {
- dump_item Left, Right;
- char Oper;
- bool force_long;
- bool unary;
- bool is_variable;
- bool string_op; // TODO -> bitop
-
- // for local vars
- mutable bool calculated;
- mutable eval_res_type result;
-
- calc_op(calc_elem& left, calc_elem& right)
- : Left(left.item)
- , Right(right.item)
- , Oper(right.oper)
- , is_variable(false)
- , calculated(false)
- , result(false)
- {
- force_long = Oper == OP_XOR || Oper == OP_BITWISE_OR || Oper == OP_BITWISE_AND ||
- Oper == OP_LOGICAL_OR || Oper == OP_LOGICAL_AND || Oper == OP_UNARY_NOT ||
- Oper == OP_UNARY_COMPLEMENT || Oper == OP_LEFT_SHIFT || Oper == OP_RIGHT_SHIFT ||
- Oper == OP_MODULUS;
- unary = Oper == OP_UNARY_NOT || Oper == OP_UNARY_COMPLEMENT || Oper == OP_UNARY_MINUS ||
- Oper == OP_LOG || Oper == OP_LOG10 || Oper == OP_ROUND;
- string_op = IsStringType(Left.type) && IsStringType(Right.type) &&
- (Oper == OP_REGEXP || Oper == OP_REGEXP_NOT || Oper == OP_EQUAL || Oper == OP_NOT_EQUAL ||
- Oper == OP_LESS || Oper == OP_LESS_OR_EQUAL || Oper == OP_GREATER || Oper == OP_GREATER_OR_EQUAL);
- if (Oper == OP_REGEXP || Oper == OP_REGEXP_NOT) {
- if (!string_op)
- ythrow yexception() << "calc-expr: regexp requested for non-strings";
- ythrow yexception() << "calc-expr: regexps currently not supported";
- }
- }
-
- Y_FORCE_INLINE void eval(const char** dd) const {
- if (is_variable) {
- if (!calculated) {
- do_eval(dd);
- calculated = true;
- }
- } else {
- do_eval(dd);
- }
- }
-
-private:
- Y_FORCE_INLINE void do_eval(const char** dd) const;
-};
-
-void calc_op::do_eval(const char** dd) const {
- eval_res_type left1 = unary ? (eval_res_type) false : Left.eval(dd);
- if (Oper == OP_QUESTION) {
- left1.to_long();
- if (left1.res_long) {
- result = Right.eval(dd);
- } else {
- result = eval_res_type(); // null
- }
- return;
- } else if (Oper == OP_COLON) {
- if (left1.is_null()) {
- result = Right.eval(dd);
- } else {
- result = left1;
- }
- return;
- }
-
- if (Y_UNLIKELY(string_op)) {
- TStringBuf left2 = Left.GetStrBuf(dd);
- TStringBuf right2 = Right.GetStrBuf(dd);
- switch (Oper) {
- case OP_REGEXP:
- result = false;
- break;
- case OP_REGEXP_NOT:
- result = false;
- break;
- case OP_EQUAL:
- result = left2 == right2;
- break;
- case OP_NOT_EQUAL:
- result = left2 != right2;
- break;
- case OP_LESS:
- result = left2 < right2;
- break;
- case OP_LESS_OR_EQUAL:
- result = left2 <= right2;
- break;
- case OP_GREATER:
- result = left2 > right2;
- break;
- case OP_GREATER_OR_EQUAL:
- result = left2 >= right2;
- break;
- default:
- assert(false);
- }
- return;
- }
-
- eval_res_type right1 = Right.eval(dd);
- if (force_long) { // logical ops will be all long
- left1.to_long();
- right1.to_long();
- }
- switch (Oper) {
- case OP_ADD:
- result = left1 + right1;
- break;
- case OP_SUBSTRACT:
- result = left1 - right1;
- break;
- case OP_MULTIPLY:
- result = left1 * right1;
- break;
- case OP_DIVIDE:
- result = left1 / right1;
- break;
- case OP_MODULUS:
- result = left1.res_long ? left1.res_long % right1.res_long : 0;
- break;
- case OP_LEFT_SHIFT:
- result = left1.res_long << right1.res_long;
- break;
- case OP_RIGHT_SHIFT:
- result = left1.res_long >> right1.res_long;
- break;
- case OP_EQUAL:
- result = left1 == right1;
- break;
- case OP_NOT_EQUAL:
- result = !(left1 == right1);
- break;
- case OP_LESS:
- result = left1 < right1;
- break;
- case OP_LESS_OR_EQUAL:
- result = !(right1 < left1);
- break; // <=
- case OP_GREATER:
- result = right1 < left1;
- break;
- case OP_GREATER_OR_EQUAL:
- result = !(left1 < right1);
- break; // >=
- case OP_XOR:
- result = left1.res_long ^ right1.res_long;
- break;
- case OP_BITWISE_OR:
- result = left1.res_long | right1.res_long;
- break;
- case OP_BITWISE_AND:
- result = left1.res_long & right1.res_long;
- break;
- case OP_LOGICAL_OR:
- result = left1.res_long || right1.res_long;
- break;
- case OP_LOGICAL_AND:
- result = left1.res_long && right1.res_long;
- break;
- case OP_UNARY_NOT:
- result = !right1.res_long;
- break;
- case OP_UNARY_COMPLEMENT:
- result = ~right1.res_long;
- break;
- case OP_UNARY_MINUS:
- result = Minus(right1);
- break;
- case OP_LOG:
- result = Log(right1);
- break;
- case OP_LOG10:
- result = Log10(right1);
- break;
- case OP_ROUND:
- result = Round(right1);
- break;
- default:
- assert(false);
- }
-}
-
-namespace {
- // copy-paste of fcat(TString)
- // we don't want it to be too slow, yet we don't want do slow down our
- // main functionality, libc fprintf, even a little
- size_t Y_PRINTF_FORMAT(2, 3) fprintf(TString* s, const char* c, ...) {
- TStringOutput so(*s);
-
- va_list params;
- va_start(params, c);
- const size_t ret = Printf(so, c, params);
- va_end(params);
-
- return ret;
- }
- size_t Y_PRINTF_FORMAT(2, 3) fprintf(IOutputStream* s, const char* c, ...) {
- va_list params;
- va_start(params, c);
- const size_t ret = Printf(*s, c, params);
- va_end(params);
-
- return ret;
- }
-}
-
-template <class TOut>
-void dump_item::print(TOut* p, const char** dd) const {
- const char* d = dd[pack_id];
- const fake* f = reinterpret_cast<const fake*>(d);
-
- switch (type) {
- case DIT_FAKE_ITEM:
- assert(false);
- break;
- case DIT_MATH_RESULT:
- assert(false);
- break; // must call eval instead
- case DIT_NAME:
- assert(false);
- break; // no op
-
- case DIT_BOOL_FIELD:
- fprintf(p, *(bool*)(d + field_offset) ? "true" : "false");
- break;
- case DIT_UI8_FIELD:
- fprintf(p, "%u", *(ui8*)(d + field_offset));
- break;
- case DIT_UI16_FIELD:
- fprintf(p, "%u", *(ui16*)(d + field_offset));
- break;
- case DIT_UI32_FIELD:
- fprintf(p, "%u", *(ui32*)(d + field_offset));
- break;
- case DIT_I64_FIELD:
- fprintf(p, "%" PRId64, *(i64*)(d + field_offset));
- break;
- case DIT_UI64_FIELD:
- fprintf(p, "%" PRIu64, *(ui64*)(d + field_offset));
- break;
- case DIT_FLOAT_FIELD:
- fprintf(p, "%.4f", *(float*)(d + field_offset));
- break;
- case DIT_DOUBLE_FIELD:
- fprintf(p, "%.7f", *(double*)(d + field_offset));
- break;
- case DIT_TIME_T32_FIELD:
- fprintf(p, "%ld", (long)*(time_t32*)(d + field_offset));
- break;
- case DIT_PF16UI32_FIELD:
- fprintf(p, "%u", (ui32) * (pf16ui32*)(d + field_offset));
- break;
- case DIT_PF16FLOAT_FIELD:
- fprintf(p, "%.4f", (float)*(pf16float*)(d + field_offset));
- break;
- case DIT_SF16FLOAT_FIELD:
- fprintf(p, "%.4f", (float)*(sf16float*)(d + field_offset));
- break;
- case DIT_STRING_FIELD:
- fprintf(p, "%s", (d + field_offset));
- break;
-
- case DIT_LONG_CONST:
- fprintf(p, "%ld", long_const);
- break;
- case DIT_FLOAT_CONST:
- fprintf(p, "%.4f", float_const);
- break;
- case DIT_STR_CONST:
- fprintf(p, "%.*s", (int)the_buf.size(), the_buf.data());
- break;
-
- case DIT_INT_FUNCTION:
- fprintf(p, "%d", (f->*int_fn)());
- break;
- case DIT_FLOAT_FUNCTION:
- fprintf(p, "%.4f", (f->*float_fn)());
- break;
- case DIT_BOOL_FUNCTION:
- fprintf(p, "%d", (f->*bool_fn)());
- break;
- case DIT_STR_FUNCTION:
- fprintf(p, "%s", (f->*str_fn)());
- break;
- case DIT_STRBUF_FUNCTION:
- the_buf.clear();
- fprintf(p, "%s", (f->*strbuf_2_fn)(the_buf, nullptr));
- break;
-
- case DIT_UI8_EXT_FUNCTION:
- fprintf(p, "%u", (*ui8_ext_fn)(f));
- break;
- case DIT_UI16_EXT_FUNCTION:
- fprintf(p, "%u", (*ui16_ext_fn)(f));
- break;
- case DIT_UI32_EXT_FUNCTION:
- fprintf(p, "%u", (*ui32_ext_fn)(f));
- break;
- case DIT_UI64_EXT_FUNCTION:
- fprintf(p, "%" PRIu64, (*ui64_ext_fn)(f));
- break;
-
- case DIT_UI8_ENUM_EQ:
- fprintf(p, "%d", *(ui8*)(d + field_offset) == enum_val);
- break;
- case DIT_UI8_ENUM_SET:
- fprintf(p, "%d", !!(*(ui8*)(d + field_offset) & enum_val));
- break;
-
- case DIT_UI16_ENUM_EQ:
- fprintf(p, "%d", *(ui16*)(d + field_offset) == enum_val);
- break;
- case DIT_UI16_ENUM_SET:
- fprintf(p, "%d", !!(*(ui16*)(d + field_offset) & enum_val));
- break;
-
- case DIT_UI32_ENUM_EQ:
- fprintf(p, "%d", *(ui32*)(d + field_offset) == enum_val);
- break;
- case DIT_UI32_ENUM_SET:
- fprintf(p, "%d", !!(*(ui32*)(d + field_offset) & enum_val));
- break;
-
- case DIT_INT_ENUM_FUNCTION_EQ:
- fprintf(p, "%d", (ui32)(f->*int_enum_fn)() == enum_val);
- break;
- case DIT_INT_ENUM_FUNCTION_SET:
- fprintf(p, "%d", !!(ui32)((f->*int_enum_fn)() & enum_val));
- break;
-
- case DIT_BOOL_FUNC_FIXED_STR:
- fprintf(p, "%u", (ui32)(f->*bool_strbuf_fn)(the_buf));
- break;
- case DIT_UI8_FUNC_FIXED_STR:
- fprintf(p, "%u", (ui32)(f->*ui8_strbuf_fn)(the_buf));
- break;
- case DIT_UI16_FUNC_FIXED_STR:
- fprintf(p, "%u", (ui32)(f->*ui16_strbuf_fn)(the_buf));
- break;
- case DIT_UI32_FUNC_FIXED_STR:
- fprintf(p, "%u", (f->*ui32_strbuf_fn)(the_buf));
- break;
- case DIT_I64_FUNC_FIXED_STR:
- fprintf(p, "%" PRId64, (f->*i64_strbuf_fn)(the_buf));
- break;
- case DIT_UI64_FUNC_FIXED_STR:
- fprintf(p, "%" PRIu64, (f->*ui64_strbuf_fn)(the_buf));
- break;
- case DIT_FLOAT_FUNC_FIXED_STR:
- fprintf(p, "%.4f", (f->*float_strbuf_fn)(the_buf));
- break;
- case DIT_DOUBLE_FUNC_FIXED_STR:
- fprintf(p, "%.7f", (f->*double_strbuf_fn)(the_buf));
- break;
-
- case DIT_RESOLVE_BY_NAME:
- fprintf(p, "%s", (f->*resolve_fn)(the_buf).data());
- break;
-
- default:
- assert(false);
- break;
- }
-}
-
-// instantiate, just for a case
-template void dump_item::print<FILE>(FILE* p, const char** dd) const;
-template void dump_item::print<TString>(TString* p, const char** dd) const;
-template void dump_item::print<IOutputStream>(IOutputStream* p, const char** dd) const;
-
-TStringBuf dump_item::GetStrBuf(const char** dd) const {
- const char* d = dd[pack_id];
- const fake* f = reinterpret_cast<const fake*>(d);
- switch (type) {
- case DIT_STRING_FIELD:
- return d + field_offset;
- case DIT_STR_CONST:
- return the_buf;
- case DIT_STR_FUNCTION:
- return (f->*str_fn)();
- case DIT_STRBUF_FUNCTION:
- the_buf.clear();
- return (f->*strbuf_2_fn)(the_buf, nullptr);
- case DIT_RESOLVE_BY_NAME:
- return (f->*resolve_fn)(the_buf);
- default:
- assert(false);
- return TStringBuf();
- }
-}
-
-// recursive
-eval_res_type dump_item::eval(const char** dd) const {
- const char* d = dd[pack_id];
- const fake* f = reinterpret_cast<const fake*>(d);
-
- switch (type) {
- case DIT_FAKE_ITEM:
- assert(false);
- return (long int)0;
- case DIT_MATH_RESULT:
- this->op->eval(dd);
- return this->op->result;
- case DIT_NAME:
- assert(false);
- return (long int)0;
-
- case DIT_BOOL_FIELD:
- return (ui32) * (bool*)(d + field_offset);
- case DIT_UI8_FIELD:
- return (ui32) * (ui8*)(d + field_offset);
- case DIT_UI16_FIELD:
- return (ui32) * (ui16*)(d + field_offset);
- case DIT_UI32_FIELD:
- return (ui32) * (ui32*)(d + field_offset);
- case DIT_I64_FIELD:
- return (long)*(i64*)(d + field_offset); // TODO: 64 bit support in calculator?
- case DIT_UI64_FIELD:
- return (long)*(ui64*)(d + field_offset); // TODO: 64 bit support in calculator?
- case DIT_FLOAT_FIELD:
- return (float)*(float*)(d + field_offset);
- case DIT_DOUBLE_FIELD:
- return *(double*)(d + field_offset);
- case DIT_TIME_T32_FIELD:
- return (long)*(time_t32*)(d + field_offset);
- case DIT_PF16UI32_FIELD:
- return (ui32) * (pf16ui32*)(d + field_offset);
- case DIT_PF16FLOAT_FIELD:
- return (float)*(pf16float*)(d + field_offset);
- case DIT_SF16FLOAT_FIELD:
- return (float)*(sf16float*)(d + field_offset);
- case DIT_STRING_FIELD:
- return !!d[field_offset]; // we don't have any string functions, just 0 if empty
-
- case DIT_LONG_CONST:
- return long_const;
- case DIT_FLOAT_CONST:
- return float_const;
- case DIT_STR_CONST:
- return !!the_buf;
-
- case DIT_INT_FUNCTION:
- return (long)(f->*int_fn)();
- case DIT_FLOAT_FUNCTION:
- return (float)(f->*float_fn)();
- case DIT_BOOL_FUNCTION:
- return (long)(f->*bool_fn)();
- case DIT_STR_FUNCTION:
- return !!*(f->*str_fn)(); // string -> int
- case DIT_STRBUF_FUNCTION:
- the_buf.clear();
- return !!*(f->*strbuf_2_fn)(the_buf, nullptr); // string -> 0/1
-
- case DIT_UI8_EXT_FUNCTION:
- return (ui32)(*ui8_ext_fn)(f);
- case DIT_UI16_EXT_FUNCTION:
- return (ui32)(*ui16_ext_fn)(f);
- case DIT_UI32_EXT_FUNCTION:
- return (ui32)(*ui32_ext_fn)(f);
- case DIT_UI64_EXT_FUNCTION:
- return (long)(*ui64_ext_fn)(f); // TODO: 64 bit support in calculator?
-
- case DIT_UI8_ENUM_EQ:
- return (ui32)(*(ui8*)(d + field_offset) == enum_val);
- case DIT_UI8_ENUM_SET:
- return !!(ui32)(*(ui8*)(d + field_offset) & enum_val);
-
- case DIT_UI16_ENUM_EQ:
- return (ui32)(*(ui16*)(d + field_offset) == enum_val);
- case DIT_UI16_ENUM_SET:
- return !!(ui32)(*(ui16*)(d + field_offset) & enum_val);
-
- case DIT_UI32_ENUM_EQ:
- return (ui32)(*(ui32*)(d + field_offset) == enum_val);
- case DIT_UI32_ENUM_SET:
- return !!(ui32)(*(ui32*)(d + field_offset) & enum_val);
-
- case DIT_INT_ENUM_FUNCTION_EQ:
- return (ui32)((ui32)(f->*int_enum_fn)() == enum_val);
- case DIT_INT_ENUM_FUNCTION_SET:
- return !!(ui32)((ui32)(f->*int_enum_fn)() & enum_val);
-
- case DIT_BOOL_FUNC_FIXED_STR:
- return (ui32)(f->*bool_strbuf_fn)(the_buf);
- case DIT_UI8_FUNC_FIXED_STR:
- return (ui32)(f->*ui8_strbuf_fn)(the_buf);
- case DIT_UI16_FUNC_FIXED_STR:
- return (ui32)(f->*ui16_strbuf_fn)(the_buf);
- case DIT_UI32_FUNC_FIXED_STR:
- return (ui32)(f->*ui32_strbuf_fn)(the_buf);
- case DIT_I64_FUNC_FIXED_STR:
- return (long)(f->*i64_strbuf_fn)(the_buf);
- case DIT_UI64_FUNC_FIXED_STR:
- return (long)(f->*ui64_strbuf_fn)(the_buf);
- case DIT_FLOAT_FUNC_FIXED_STR:
- return (float)(f->*float_strbuf_fn)(the_buf);
- case DIT_DOUBLE_FUNC_FIXED_STR:
- return (double)(f->*double_strbuf_fn)(the_buf);
-
- case DIT_RESOLVE_BY_NAME:
- return !!(f->*resolve_fn)(the_buf);
-
- default:
- assert(false);
- break;
- }
-
- // unreached
- return eval_res_type(false);
-}
-
-void dump_item::set_arrind(int arrind) {
- switch (type) {
- case DIT_BOOL_FIELD:
- field_offset += arrind * sizeof(bool);
- break;
- case DIT_UI8_FIELD:
- field_offset += arrind * sizeof(ui8);
- break;
- case DIT_UI16_FIELD:
- field_offset += arrind * sizeof(ui16);
- break;
- case DIT_UI32_FIELD:
- field_offset += arrind * sizeof(ui32);
- break;
- case DIT_I64_FIELD:
- field_offset += arrind * sizeof(i64);
- break;
- case DIT_UI64_FIELD:
- field_offset += arrind * sizeof(ui64);
- break;
- case DIT_FLOAT_FIELD:
- field_offset += arrind * sizeof(float);
- break;
- case DIT_DOUBLE_FIELD:
- field_offset += arrind * sizeof(double);
- break;
- case DIT_TIME_T32_FIELD:
- field_offset += arrind * sizeof(time_t32);
- break;
- case DIT_PF16UI32_FIELD:
- field_offset += arrind * sizeof(pf16ui32);
- break;
- case DIT_PF16FLOAT_FIELD:
- field_offset += arrind * sizeof(pf16float);
- break;
- case DIT_SF16FLOAT_FIELD:
- field_offset += arrind * sizeof(sf16float);
- break;
- default:
- break;
- }
-}
-
-static str_spn FieldNameChars("a-zA-Z0-9_$", true);
-static str_spn MathOpChars("-+=*%/&|<>()!~^?:#", true);
-static str_spn SpaceChars("\t\n\r ", true);
-
-TFieldCalculatorBase::TFieldCalculatorBase() {
-}
-
-TFieldCalculatorBase::~TFieldCalculatorBase() = default;
-
-bool TFieldCalculatorBase::item_by_name(dump_item& it, const char* name) const {
- for (size_t i = 0; i < named_dump_items.size(); i++) {
- const named_dump_item* list = named_dump_items[i].first;
- size_t sz = named_dump_items[i].second;
- for (unsigned int n = 0; n < sz; n++) {
- if (!stricmp(name, list[n].name)) {
- it = list[n].item;
- it.pack_id = i;
- return true;
- }
- }
- }
- return false;
-}
-
-bool TFieldCalculatorBase::get_local_var(dump_item& dst, char* var_name) {
- TMap<const char*, dump_item>::const_iterator it = local_vars.find(var_name);
- if (it == local_vars.end()) {
- // New local variable
- dst.type = DIT_LOCAL_VARIABLE;
- dst.local_var_name = pool.append(var_name);
- return false;
- } else {
- dst = it->second;
- return true;
- }
-}
-
-char* TFieldCalculatorBase::get_field(dump_item& dst, char* s) {
- if (!stricmp(s, "name")) {
- dst.type = DIT_NAME;
- return s + 4; // leave there 0
- }
-
- if (*s == '"' || *s == '\'') {
- char* end = strchr(s + 1, *s);
- bool hasEsc = false;
- while (end && end > s + 1 && end[-1] == '\\') {
- end = strchr(end + 1, *s);
- hasEsc = true;
- }
- if (!end)
- ythrow yexception() << "calc-expr: unterminated string constant at " << s;
- dst.type = DIT_STR_CONST;
- dst.the_buf.assign(s + 1, end);
- if (hasEsc)
- SubstGlobal(dst.the_buf, *s == '"' ? "\\\"" : "\\'", *s == '"' ? "\"" : "'");
- dst.set_arrind(0); // just for a case
- return end + 1;
- }
-
- bool is_number = isdigit((ui8)*s) || (*s == '+' || *s == '-') && isdigit((ui8)s[1]), is_float = false;
- char* end = FieldNameChars.cbrk(s + is_number);
- if (is_number && *end == '.') {
- is_float = true;
- end = FieldNameChars.cbrk(end + 1);
- }
- char* next = SpaceChars.cbrk(end);
- int arr_index = 0;
- bool has_arr_index = false;
- if (*next == '[') {
- arr_index = atoi(next + 1);
- has_arr_index = true;
- next = strchr(next, ']');
- if (!next)
- ythrow yexception() << "calc-expr: No closing ']' for '" << s << "'";
- next = SpaceChars.cbrk(next + 1);
- }
- char end_sav = *end;
- *end = 0;
-
- if (!item_by_name(dst, s)) {
- if (!is_number) {
- get_local_var(dst, s);
- } else if (is_float) {
- dst = (float)strtod(s, nullptr);
- } else
- dst = strtol(s, nullptr, 10);
-
- dst.pack_id = 0;
- *end = end_sav;
- return next;
- }
-
- // check array/not array
- if (has_arr_index && !dst.is_array_field())
- ythrow yexception() << "calc-expr: field " << s << " is not an array";
-
- //if (!has_arr_index && dst.is_array_field())
- // yexception("calc-expr: field %s is array, index required", s);
-
- if (has_arr_index && (arr_index < 0 || arr_index >= dst.arr_length))
- ythrow yexception() << "calc-expr: array index [" << arr_index << "] is out of range for field " << s << " (length is " << dst.arr_length << ")";
-
- *end = end_sav;
- dst.set_arrind(arr_index);
- return next;
-}
-
-// BEGIN Stack calculator functions
-inline char* skipspace(char* c, int& bracket_depth) {
- while ((ui8)*c <= ' ' && *c || *c == '(' || *c == ')') {
- if (*c == '(')
- bracket_depth++;
- else if (*c == ')')
- bracket_depth--;
- c++;
- }
- return c;
-}
-
-void ensure_defined(const dump_item& item) {
- if (item.type == DIT_LOCAL_VARIABLE) {
- ythrow yexception() << "Usage of non-defined field or local variable '" << item.local_var_name << "'";
- }
-}
-
-void TFieldCalculatorBase::emit_op(TVector<calc_op>& ops, calc_elem& left, calc_elem& right) {
- int out_op = ops.size();
- char oper = right.oper;
- ensure_defined(right.item);
- if (oper == OP_ASSIGN) {
- if (left.item.type != DIT_LOCAL_VARIABLE) {
- ythrow yexception() << "Assignment only to local variables is allowed";
- }
- if (local_vars.find(left.item.local_var_name) != local_vars.end()) {
- ythrow yexception() << "Reassignment to the local variable " << left.item.local_var_name << " is not allowed";
- }
- local_vars[left.item.local_var_name] = right.item;
- if (right.item.type == DIT_MATH_RESULT) {
- calc_ops[right.item.arr_ind].is_variable = true;
- }
- left = right;
- } else {
- ensure_defined(left.item);
- ops.push_back(calc_op(left, right));
- left.item.type = DIT_MATH_RESULT;
- left.item.arr_ind = out_op;
- }
-}
-
-inline int get_op_prio(char c) {
- switch (c) {
- case OP_ASSIGN:
- return 1;
- case OP_QUESTION:
- case OP_COLON:
- return 2;
- case OP_LOGICAL_OR:
- return 3;
- case OP_LOGICAL_AND:
- return 4;
- case OP_BITWISE_OR:
- return 5;
- case OP_XOR:
- return 6;
- case OP_BITWISE_AND:
- return 7;
- case OP_EQUAL:
- case OP_NOT_EQUAL:
- return 8;
- case OP_LESS:
- case OP_LESS_OR_EQUAL:
- case OP_GREATER:
- case OP_GREATER_OR_EQUAL:
- return 9;
- case OP_LEFT_SHIFT:
- case OP_RIGHT_SHIFT:
- return 10;
- case OP_ADD:
- case OP_SUBSTRACT:
- return 11;
- case OP_MULTIPLY:
- case OP_DIVIDE:
- case OP_MODULUS:
- return 12;
- case OP_REGEXP:
- case OP_REGEXP_NOT:
- return 13;
- case OP_UNARY_NOT:
- case OP_UNARY_COMPLEMENT:
- case OP_UNARY_MINUS:
- case OP_LOG:
- case OP_LOG10:
- case OP_ROUND:
- return 14;
- default:
- return 0;
- }
-}
-
-Operators get_oper(char*& c, bool unary_op_near) {
- Operators cur_oper = OP_UNKNOWN;
- switch (*c++) {
- case '&':
- if (*c == '&')
- cur_oper = OP_LOGICAL_AND, c++;
- else
- cur_oper = OP_BITWISE_AND;
- break;
- case '|':
- if (*c == '|')
- cur_oper = OP_LOGICAL_OR, c++;
- else
- cur_oper = OP_BITWISE_OR;
- break;
- case '<':
- if (*c == '=')
- cur_oper = OP_LESS_OR_EQUAL, c++;
- else if (*c == '<')
- cur_oper = OP_LEFT_SHIFT, c++;
- else
- cur_oper = OP_LESS;
- break;
- case '>':
- if (*c == '=')
- cur_oper = OP_GREATER_OR_EQUAL, c++;
- else if (*c == '>')
- cur_oper = OP_RIGHT_SHIFT, c++;
- else
- cur_oper = OP_GREATER;
- break;
- case '!':
- if (*c == '=')
- cur_oper = OP_NOT_EQUAL, c++;
- else if (*c == '~')
- cur_oper = OP_REGEXP_NOT, c++;
- else
- cur_oper = OP_UNARY_NOT;
- break;
- case '=':
- if (*c == '=')
- cur_oper = OP_EQUAL, c++;
- else if (*c == '~')
- cur_oper = OP_REGEXP, c++;
- else
- cur_oper = OP_ASSIGN;
- break;
- case '-':
- if (unary_op_near)
- cur_oper = OP_UNARY_MINUS;
- else
- cur_oper = OP_SUBSTRACT;
- break;
- case '#':
- if (!strncmp(c, "LOG#", 4)) {
- cur_oper = OP_LOG;
- c += 4;
- } else if (!strncmp(c, "LOG10#", 6)) {
- cur_oper = OP_LOG10;
- c += 6;
- } else if (!strncmp(c, "ROUND#", 6)) {
- cur_oper = OP_ROUND;
- c += 6;
- }
- break;
- case '+':
- cur_oper = OP_ADD;
- break;
- case '*':
- cur_oper = OP_MULTIPLY;
- break;
- case '/':
- cur_oper = OP_DIVIDE;
- break;
- case '%':
- cur_oper = OP_MODULUS;
- break;
- case '^':
- cur_oper = OP_XOR;
- break;
- case '~':
- cur_oper = OP_UNARY_COMPLEMENT;
- break;
- case '?':
- cur_oper = OP_QUESTION;
- break;
- case ':':
- cur_oper = OP_COLON;
- break;
- }
- return cur_oper;
-}
-// END Stack calculator functions
-
-void TFieldCalculatorBase::Compile(char** field_names, int field_count) {
- out_el = 0, out_cond = 0;
- autoarray<dump_item>(field_count).swap(printouts);
- autoarray<dump_item>(field_count).swap(conditions);
- local_vars.clear();
-
- // parse arguments into calculator's "pseudo-code"
- for (int el = 0; el < field_count; el++) {
- char* c = field_names[el];
- bool is_expr = !!*MathOpChars.brk(c), is_cond = *c == '?';
- if (is_cond)
- c++;
- if (!is_expr && !is_cond) {
- get_field(printouts[out_el], c);
- ensure_defined(printouts[out_el]);
- ++out_el;
- continue;
- } else { // Stack Calculator
- const int maxstack = 64;
- calc_elem fstack[maxstack]; // calculator's stack
- int bdepth = 0; // brackets depth
- int stack_cur = -1;
- bool unary_op_near = false; // indicates that the next operator in unary
- bool had_assignment_out_of_brackets = false;
- int uop_seq = 0; // maintains right-to left order for unary operators
- while (*(c = skipspace(c, bdepth))) {
- /** https://wiki.yandex.ru/JandeksPoisk/Antispam/OwnersData/attselect#calc */
- //printf("1.%i c = '%s'\n", unary_op_near, c);
- Operators cur_oper = OP_UNKNOWN;
- int op_prio = 0;
- if (stack_cur >= 0) {
- cur_oper = get_oper(c, unary_op_near);
- op_prio = get_op_prio(cur_oper);
- if (!op_prio)
- ythrow yexception() << "calc-expr: Unsupported operator '" << c[-1] << "'";
- op_prio += bdepth * 256 + uop_seq;
- if (unary_op_near)
- uop_seq += 20;
- while (op_prio <= fstack[stack_cur].op_prio && stack_cur > 0) {
- emit_op(calc_ops, fstack[stack_cur - 1], fstack[stack_cur]);
- stack_cur--;
- }
- }
- //printf("2.%i c = '%s'\n", unary_op_near, c);
- had_assignment_out_of_brackets |= (bdepth == 0 && cur_oper == OP_ASSIGN);
- c = skipspace(c, bdepth);
- unary_op_near = *c == '-' && !isdigit((ui8)c[1]) || *c == '~' || (*c == '!' && c[1] != '=') ||
- !strncmp(c, "#LOG#", 5) || !strncmp(c, "#LOG10#", 7) || !strncmp(c, "#ROUND#", 7);
- if (!unary_op_near)
- uop_seq = 0;
- if (stack_cur >= maxstack - 1)
- ythrow yexception() << "calc-expr: Math eval stack overflow!\n";
- stack_cur++;
- fstack[stack_cur].oper = cur_oper;
- fstack[stack_cur].op_prio = op_prio;
- //printf("3.%i c = '%s'\n", unary_op_near, c);
- if (unary_op_near)
- fstack[stack_cur].item = dump_item();
- else
- c = get_field(fstack[stack_cur].item, c);
- }
- while (stack_cur > 0) {
- emit_op(calc_ops, fstack[stack_cur - 1], fstack[stack_cur]);
- stack_cur--;
- }
- ensure_defined(fstack[0].item);
- if (is_cond) {
- if (had_assignment_out_of_brackets)
- ythrow yexception() << "Assignment in condition. (Did you mean '==' instead of '='?)";
- if (fstack[0].item.type != DIT_FAKE_ITEM) // Skip empty conditions: "?()".
- conditions[out_cond++] = fstack[0].item;
- } else if (!had_assignment_out_of_brackets) {
- printouts[out_el++] = fstack[0].item;
- }
- }
- }
- // calc_ops will not grow any more, so arr_ind -> op
- for (int n = 0; n < out_cond; n++)
- conditions[n].rewrite_op(calc_ops.data());
- for (int n = 0; n < out_el; n++)
- printouts[n].rewrite_op(calc_ops.data());
- for (auto& local_var : local_vars) {
- local_var.second.rewrite_op(calc_ops.data());
- }
- for (int n = 0; n < (int)calc_ops.size(); n++) {
- calc_ops[n].Left.rewrite_op(calc_ops.data());
- calc_ops[n].Right.rewrite_op(calc_ops.data());
- }
-}
-
-void dump_item::rewrite_op(const calc_op* ops) {
- if (type == DIT_MATH_RESULT)
- op = ops + arr_ind;
-}
-
-void TFieldCalculatorBase::MarkLocalVarsAsUncalculated() {
- for (auto& local_var : local_vars) {
- if (local_var.second.type == DIT_MATH_RESULT) {
- local_var.second.op->calculated = false;
- }
- }
-}
-
-bool TFieldCalculatorBase::Cond(const char** d) {
- MarkLocalVarsAsUncalculated();
- for (int n = 0; n < out_cond; n++) {
- /** https://wiki.yandex.ru/JandeksPoisk/Antispam/OwnersData/attselect#conditions */
- eval_res_type res = conditions[n].eval(d);
- bool is_true = res.type == 0 ? !!res.res_ui32 : res.type == 1 ? !!res.res_long : !!res.res_dbl;
- if (!is_true)
- return false;
- }
- return true;
-}
-
-bool TFieldCalculatorBase::CondById(const char** d, int condNumber) {
- MarkLocalVarsAsUncalculated();
- if (condNumber >= out_cond)
- return false;
- eval_res_type res = conditions[condNumber].eval(d);
- bool is_true = res.type == 0 ? !!res.res_ui32 : res.type == 1 ? !!res.res_long : !!res.res_dbl;
- if (!is_true)
- return false;
- return true;
-}
-
-void TFieldCalculatorBase::Print(FILE* p, const char** d, const char* Name) {
- for (int n = 0; n < out_el; n++) {
- if (printouts[n].type == DIT_NAME) {
- fprintf(p, "%s", Name);
- } else if (printouts[n].type == DIT_MATH_RESULT) { // calculate
- eval_res_type res = printouts[n].eval(d);
- switch (res.type) {
- case 0:
- fprintf(p, "%u", res.res_ui32);
- break;
- case 1:
- fprintf(p, "%ld", res.res_long);
- break;
- case 2:
- fprintf(p, "%f", res.res_dbl);
- break;
- }
- } else {
- printouts[n].print(p, d);
- }
- fprintf(p, n != out_el - 1 ? "\t" : "\n");
- }
-}
-
-void TFieldCalculatorBase::CalcAll(const char** d, TVector<float>& result) const {
- result.clear();
- for (int n = 0; n < out_el; ++n) {
- if (printouts[n].type == DIT_MATH_RESULT || printouts[n].type == DIT_FLOAT_FIELD) {
- eval_res_type res = printouts[n].eval(d);
- result.push_back(res.res_dbl);
- }
- }
-}
-
-void TFieldCalculatorBase::SelfTest() {
- if (out_el < 1)
- ythrow yexception() << "Please specify conditions for test mode";
- const char* dummy = "";
- eval_res_type res = printouts[0].eval(&dummy);
- switch (res.type) {
- case 0:
- printf("%u\n", res.res_ui32);
- break;
- case 1:
- printf("%ld\n", res.res_long);
- break;
- case 2:
- printf("%f\n", res.res_dbl);
- break;
- }
-}
-
-void TFieldCalculatorBase::PrintDiff(const char* rec1, const char* rec2) {
- for (size_t n = 0; n < named_dump_items[0].second; n++) {
- const dump_item& field = named_dump_items[0].first[n].item;
- if (!field.is_field())
- continue; // not really a field
- for (int ind = 0, arrsz = field.is_array_field() ? field.arr_length : 1; ind < arrsz; ind++) {
- intptr_t sav_field_offset = field.field_offset;
- const_cast<dump_item&>(field).set_arrind(ind);
- if (field.eval(&rec1) == field.eval(&rec2)) {
- const_cast<dump_item&>(field).field_offset = sav_field_offset;
- continue;
- }
- if (field.is_array_field())
- printf("\t%s[%i]: ", named_dump_items[0].first[n].name, ind);
- else
- printf("\t%s: ", named_dump_items[0].first[n].name);
- field.print(stdout, &rec1);
- printf(" -> ");
- field.print(stdout, &rec2);
- const_cast<dump_item&>(field).field_offset = sav_field_offset;
- }
- }
-}
-
-void TFieldCalculatorBase::DumpAll(IOutputStream& s, const char** d, const TStringBuf& delim) {
- bool firstPrinted = false;
- for (size_t k = 0; k < named_dump_items.size(); k++) {
- const named_dump_item* fields = named_dump_items[k].first;
- size_t numFields = named_dump_items[k].second;
- const char* obj = d[k];
- for (size_t n = 0; n < numFields; n++) {
- const dump_item& field = fields[n].item;
- if (!field.is_field())
- continue;
- for (int ind = 0, arrsz = field.is_array_field() ? field.arr_length : 1; ind < arrsz; ind++) {
- if (firstPrinted)
- s << delim;
- else
- firstPrinted = true;
- s << fields[n].name;
- if (field.is_array_field())
- Printf(s, "[%i]", ind);
- s << "=";
- intptr_t sav_field_offset = field.field_offset;
- const_cast<dump_item&>(field).set_arrind(ind);
- field.print(&s, &obj);
- const_cast<dump_item&>(field).field_offset = sav_field_offset;
- }
- }
- }
-}
diff --git a/library/cpp/fieldcalc/field_calc.h b/library/cpp/fieldcalc/field_calc.h
deleted file mode 100644
index 46bf371a60..0000000000
--- a/library/cpp/fieldcalc/field_calc.h
+++ /dev/null
@@ -1,136 +0,0 @@
-#pragma once
-
-#include <cstdio>
-
-#include <library/cpp/deprecated/autoarray/autoarray.h>
-#include <util/generic/map.h>
-#include <util/generic/vector.h>
-#include <util/memory/segmented_string_pool.h>
-
-struct dump_item;
-struct calc_op;
-struct named_dump_item;
-struct calc_elem;
-class IOutputStream;
-
-template <class T>
-std::pair<const named_dump_item*, size_t> get_named_dump_items();
-
-class TFieldCalculatorBase {
-private:
- segmented_string_pool pool;
- void emit_op(TVector<calc_op>& ops, calc_elem& left, calc_elem& right);
- void MarkLocalVarsAsUncalculated();
-
-protected:
- autoarray<dump_item> printouts, conditions;
- int out_el, out_cond;
- TVector<calc_op> calc_ops; // operands for calculator, indexed by arr_ind for DIT_math_result
-
- TVector<std::pair<const named_dump_item*, size_t>> named_dump_items;
- TMap<const char*, dump_item> local_vars;
-
- char* get_field(dump_item& dst, char* s);
- bool get_local_var(dump_item& dst, char* s);
- virtual bool item_by_name(dump_item& it, const char* name) const;
-
- TFieldCalculatorBase();
- virtual ~TFieldCalculatorBase();
-
- bool Cond(const char** d);
- bool CondById(const char** d, int condNumber);
- void Print(FILE* p, const char** d, const char* Name);
- void Compile(char** field_names, int field_count);
- void SelfTest();
- void PrintDiff(const char* d1, const char* d2);
- void CalcAll(const char** d, TVector<float>& result) const;
- void DumpAll(IOutputStream& s, const char** d, const TStringBuf& delim);
-};
-
-template <class T>
-class TFieldCalculator: protected TFieldCalculatorBase {
-public:
- TFieldCalculator() {
- named_dump_items.push_back(get_named_dump_items<T>());
- }
-
- ~TFieldCalculator() override = default;
-
- bool Cond(const T& d) {
- const char* dd = reinterpret_cast<const char*>(&d);
- return TFieldCalculatorBase::Cond(&dd);
- }
-
- bool CondById(const T& d, int condNumber) {
- const char* dd = reinterpret_cast<const char*>(&d);
- return TFieldCalculatorBase::CondById(&dd, condNumber);
- }
-
- void Print(const T& d, const char* Name) {
- const char* dd = reinterpret_cast<const char*>(&d);
- return TFieldCalculatorBase::Print(stdout, &dd, Name);
- }
-
- void Print(FILE* p, const T& d, const char* Name) {
- const char* dd = reinterpret_cast<const char*>(&d);
- return TFieldCalculatorBase::Print(p, &dd, Name);
- }
-
- size_t Compile(char** field_names, int field_count) {
- TFieldCalculatorBase::Compile(field_names, field_count);
- return out_el; // number of fields printed
- }
-
- void SelfTest() {
- return TFieldCalculatorBase::SelfTest();
- }
-
- void PrintDiff(const T& d1, const T& d2) {
- return TFieldCalculatorBase::PrintDiff((const char*)&d1, (const char*)&d2);
- }
-
- void CalcAll(const T& d, TVector<float>& result) const {
- const char* dd = reinterpret_cast<const char*>(&d);
- return TFieldCalculatorBase::CalcAll(&dd, result);
- }
-
- // it appends to `result', clear it yourself
- void DumpAll(IOutputStream& s, const T& d, const TStringBuf& delim) {
- const char* dd = reinterpret_cast<const char*>(&d);
- return TFieldCalculatorBase::DumpAll(s, &dd, delim);
- }
-};
-
-template <class T, class T2>
-class TFieldCalculator2: protected TFieldCalculator<T> {
-public:
- TFieldCalculator2() {
- TFieldCalculator<T>::named_dump_items.push_back(get_named_dump_items<T2>());
- }
-
- ~TFieldCalculator2() override = default;
-
- bool Cond(const T& d, const T2& d2) {
- const char* dd[2] = {reinterpret_cast<const char*>(&d), reinterpret_cast<const char*>(&d2)};
- return TFieldCalculatorBase::Cond(dd);
- }
-
- bool CondById(const T& d, const T2& d2, int condNumber) {
- const char* dd[2] = {reinterpret_cast<const char*>(&d), reinterpret_cast<const char*>(&d2)};
- return TFieldCalculatorBase::CondById(dd, condNumber);
- }
-
- void Print(const T& d, const T2& d2, const char* Name) {
- const char* dd[2] = {reinterpret_cast<const char*>(&d), reinterpret_cast<const char*>(&d2)};
- return TFieldCalculatorBase::Print(stdout, dd, Name);
- }
-
- void Print(FILE* p, const T& d, const T2& d2, const char* Name) {
- const char* dd[2] = {reinterpret_cast<const char*>(&d), reinterpret_cast<const char*>(&d2)};
- return TFieldCalculatorBase::Print(p, dd, Name);
- }
-
- size_t Compile(char** field_names, int field_count) {
- return TFieldCalculator<T>::Compile(field_names, field_count);
- }
-};
diff --git a/library/cpp/fieldcalc/field_calc_int.h b/library/cpp/fieldcalc/field_calc_int.h
deleted file mode 100644
index 5f71fafbda..0000000000
--- a/library/cpp/fieldcalc/field_calc_int.h
+++ /dev/null
@@ -1,593 +0,0 @@
-#pragma once
-
-#include <cmath>
-
-#include <util/system/defaults.h>
-#include <util/system/yassert.h>
-#include <util/memory/alloc.h>
-#include <util/generic/yexception.h>
-
-#include "lossy_types.h"
-#include "field_calc.h"
-
-// eval_res_type
-struct eval_res_type {
- union {
- ui32 res_ui32;
- long res_long;
- double res_dbl;
- };
- int type;
- eval_res_type(ui32 v)
- : res_ui32(v)
- , type(0)
- {
- }
- eval_res_type(long v)
- : res_long(v)
- , type(1)
- {
- }
- eval_res_type(bool v)
- : res_long(v)
- , type(1)
- {
- }
- eval_res_type(double v)
- : res_dbl(v)
- , type(2)
- {
- }
- // a special null value for ternary operator
- explicit eval_res_type()
- : type(3)
- {
- }
- operator ui32() const;
- operator long() const;
- operator double() const;
- void to_long();
- bool is_null() const;
-};
-
-inline bool eval_res_type::is_null() const {
- return type == 3;
-}
-
-inline void eval_res_type::to_long() {
- if (type == 0)
- res_long = res_ui32;
- else if (type == 2)
- res_long = (long)res_dbl;
- type = 1;
-}
-
-inline eval_res_type::operator ui32() const {
- assert(type == 0);
- return res_ui32;
-}
-
-inline eval_res_type::operator long() const {
- assert(type == 0 || type == 1);
- return type == 1 ? res_long : res_ui32;
-}
-
-inline eval_res_type::operator double() const {
- return type == 2 ? res_dbl : type == 1 ? (double)res_long : (double)res_ui32;
-}
-
-inline eval_res_type operator+(const eval_res_type& a, const eval_res_type& b) {
- switch (std::max(a.type, b.type)) {
- case 0:
- return (ui32)a + (ui32)b;
- case 1:
- return (long)a + (long)b;
- /*case 2*/ default:
- return (double)a + (double)b;
- }
-}
-
-inline eval_res_type operator-(const eval_res_type& a, const eval_res_type& b) {
- switch (std::max(a.type, b.type)) {
- case 0:
- case 1:
- return (long)a - (long)b;
- /*case 2*/ default:
- return (double)a - (double)b;
- }
-}
-
-inline eval_res_type Minus(const eval_res_type& a) {
- switch (a.type) {
- case 0:
- return -(long)a.res_ui32;
- case 1:
- return -a.res_long;
- /*case 2*/ default:
- return -a.res_dbl;
- }
-}
-
-inline eval_res_type Log(const eval_res_type& a) {
- switch (a.type) {
- case 0:
- return log(a.res_ui32);
- case 1:
- return log(a.res_long);
- /*case 2*/ default:
- return log(a.res_dbl);
- }
-}
-
-inline eval_res_type Log10(const eval_res_type& a) {
- switch (a.type) {
- case 0:
- return log10(a.res_ui32);
- case 1:
- return log10(a.res_long);
- /*case 2*/ default:
- return log10(a.res_dbl);
- }
-}
-
-inline eval_res_type Round(const eval_res_type& a) {
- switch (a.type) {
- case 0:
- return a.res_ui32;
- case 1:
- return a.res_long;
- /*case 2*/ default:
- return round(a.res_dbl);
- }
-}
-
-inline bool operator==(const eval_res_type& a, const eval_res_type& b) {
- switch (std::max(a.type, b.type)) {
- case 0:
- return (ui32)a == (ui32)b;
- case 1:
- return (long)a == (long)b;
- /*case 2*/ default:
- return (double)a == (double)b;
- }
-}
-
-inline bool operator<(const eval_res_type& a, const eval_res_type& b) {
- switch (std::max(a.type, b.type)) {
- case 0:
- return (ui32)a < (ui32)b;
- case 1:
- return (long)a < (long)b;
- /*case 2*/ default:
- return (double)a < (double)b;
- }
-}
-
-inline eval_res_type operator*(const eval_res_type& a, const eval_res_type& b) {
- switch (std::max(a.type, b.type)) {
- case 0:
- return (ui32)a * (ui32)b;
- case 1:
- return (long)a * (long)b;
- /*case 2*/ default:
- return (double)a * (double)b;
- }
-}
-
-inline double operator/(const eval_res_type& a, const eval_res_type& b) {
- double a1 = a, b1 = b;
- if (b1 == 0) {
- if (a1 == 0)
- return 0.; // assume that a should be 0
- ythrow yexception() << "Division by zero"; // TODO: show parameter names
- }
- return a1 / b1;
-}
-
-// dump_item
-enum EDumpItemType {
- DIT_FAKE_ITEM, // fake item - value never used
- DIT_MATH_RESULT, // eval result
- DIT_NAME,
-
- DIT_FIELDS_START, // Start of item types for real fields
-
- DIT_BOOL_FIELD,
- DIT_UI8_FIELD,
- DIT_UI16_FIELD,
- DIT_UI32_FIELD,
- DIT_I64_FIELD,
- DIT_UI64_FIELD,
- DIT_FLOAT_FIELD,
- DIT_DOUBLE_FIELD,
- DIT_TIME_T32_FIELD,
- DIT_PF16UI32_FIELD,
- DIT_PF16FLOAT_FIELD,
- DIT_SF16FLOAT_FIELD,
- DIT_STRING_FIELD, // new
-
- DIT_FIELDS_END, // End of item types for real fields
-
- DIT_LONG_CONST,
- DIT_FLOAT_CONST,
- DIT_STR_CONST,
-
- DIT_INT_FUNCTION,
- DIT_FLOAT_FUNCTION,
- DIT_BOOL_FUNCTION,
- DIT_STR_FUNCTION, // new
- DIT_STRBUF_FUNCTION, // new
-
- DIT_UI8_EXT_FUNCTION,
- DIT_UI16_EXT_FUNCTION,
- DIT_UI32_EXT_FUNCTION,
- DIT_UI64_EXT_FUNCTION,
-
- DIT_UI8_ENUM_EQ,
- DIT_UI8_ENUM_SET,
- DIT_UI16_ENUM_EQ,
- DIT_UI16_ENUM_SET,
- DIT_UI32_ENUM_EQ,
- DIT_UI32_ENUM_SET,
- DIT_INT_ENUM_FUNCTION_EQ,
- DIT_INT_ENUM_FUNCTION_SET,
-
- DIT_BOOL_FUNC_FIXED_STR,
- DIT_UI8_FUNC_FIXED_STR,
- DIT_UI16_FUNC_FIXED_STR,
- DIT_UI32_FUNC_FIXED_STR,
- DIT_I64_FUNC_FIXED_STR,
- DIT_UI64_FUNC_FIXED_STR,
- DIT_FLOAT_FUNC_FIXED_STR,
- DIT_DOUBLE_FUNC_FIXED_STR,
-
- DIT_RESOLVE_BY_NAME, //new - for external functions
-
- DIT_LOCAL_VARIABLE
-};
-
-inline bool IsStringType(EDumpItemType type) {
- return type == DIT_STRING_FIELD || type == DIT_STR_CONST || type == DIT_STR_FUNCTION || type == DIT_STRBUF_FUNCTION || type == DIT_RESOLVE_BY_NAME;
-}
-
-struct fake {};
-
-struct calc_op;
-
-typedef int (fake::*int_fn_t)() const;
-typedef float (fake::*float_fn_t)() const;
-typedef bool (fake::*bool_fn_t)() const;
-typedef ui16 (fake::*ui16_fn_t)() const;
-typedef ui32 (fake::*ui32_fn_t)() const;
-typedef bool (fake::*bool_strbuf_fn_t)(const TStringBuf&) const; // string -> bool
-typedef ui8 (fake::*ui8_strbuf_fn_t)(const TStringBuf&) const; // string -> ui8
-typedef ui16 (fake::*ui16_strbuf_fn_t)(const TStringBuf&) const; // string -> ui16
-typedef ui32 (fake::*ui32_strbuf_fn_t)(const TStringBuf&) const; // string -> ui32
-typedef i64 (fake::*i64_strbuf_fn_t)(const TStringBuf&) const; // string -> i64
-typedef ui64 (fake::*ui64_strbuf_fn_t)(const TStringBuf&) const; // string -> ui64
-typedef float (fake::*float_strbuf_fn_t)(const TStringBuf&) const; // string -> float
-typedef double (fake::*double_strbuf_fn_t)(const TStringBuf&) const; // string -> double
-typedef const char* (fake::*str_fn_t)() const;
-typedef const char* (fake::*strbuf_2_fn_t)(TString& buf, const char* nul) const;
-typedef TStringBuf (fake::*resolve_fn_t)(const TStringBuf&) const; // string -> string, $var -> "value"
-
-// note: we can not reuse the above signatures, calling conventions may differ
-typedef ui8 (*ui8_ext_fn_t)(const fake*);
-typedef ui16 (*ui16_ext_fn_t)(const fake*);
-typedef ui32 (*ui32_ext_fn_t)(const fake*);
-typedef ui64 (*ui64_ext_fn_t)(const fake*);
-
-struct dump_item {
- EDumpItemType type;
- int pack_id = 0;
-
- union {
- // fields
- intptr_t field_offset;
-
- // constants
- long long_const;
- float float_const;
-
- // functions
- int_fn_t int_fn;
- float_fn_t float_fn;
- bool_fn_t bool_fn;
- str_fn_t str_fn;
- strbuf_2_fn_t strbuf_2_fn;
- resolve_fn_t resolve_fn;
-
- bool_strbuf_fn_t bool_strbuf_fn;
- ui8_strbuf_fn_t ui8_strbuf_fn;
- ui16_strbuf_fn_t ui16_strbuf_fn;
- ui32_strbuf_fn_t ui32_strbuf_fn;
- i64_strbuf_fn_t i64_strbuf_fn;
- ui64_strbuf_fn_t ui64_strbuf_fn;
- float_strbuf_fn_t float_strbuf_fn;
- double_strbuf_fn_t double_strbuf_fn;
-
- ui8_ext_fn_t ui8_ext_fn;
- ui16_ext_fn_t ui16_ext_fn;
- ui32_ext_fn_t ui32_ext_fn;
- ui64_ext_fn_t ui64_ext_fn;
-
- // enum
- int_fn_t int_enum_fn;
-
- // for DIT_MATH_RESULT
- const calc_op* op;
- };
-
- // for enum
- ui32 enum_val;
-
- // for local vars, also used to mark accessor functions to use them in dump
- const char* local_var_name = nullptr;
-
- int arr_ind; // externally initialized!
- int arr_length;
-
- mutable TString the_buf; // buffer for string function, string constants also here
-
- // Ctors
- dump_item()
- : type(DIT_FAKE_ITEM)
- , field_offset(0)
- {
- }
-
- dump_item(bool* ptr, int arrlen = 0)
- : type(DIT_BOOL_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(ui8* ptr, int arrlen = 0)
- : type(DIT_UI8_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(ui16* ptr, int arrlen = 0)
- : type(DIT_UI16_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(ui32* ptr, int arrlen = 0)
- : type(DIT_UI32_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(i64* ptr, int arrlen = 0)
- : type(DIT_I64_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(ui64* ptr, int arrlen = 0)
- : type(DIT_UI64_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(float* ptr, int arrlen = 0)
- : type(DIT_FLOAT_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(double* ptr, int arrlen = 0)
- : type(DIT_DOUBLE_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(time_t32* ptr, int arrlen = 0)
- : type(DIT_TIME_T32_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(pf16ui32* ptr, int arrlen = 0)
- : type(DIT_PF16UI32_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(pf16float* ptr, int arrlen = 0)
- : type(DIT_PF16FLOAT_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(sf16float* ptr, int arrlen = 0)
- : type(DIT_SF16FLOAT_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
- dump_item(char* ptr, int arrlen = 0)
- : type(DIT_STRING_FIELD)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , arr_length(arrlen)
- {
- }
-
- dump_item(long val)
- : type(DIT_LONG_CONST)
- , long_const(val)
- {
- }
- dump_item(float val)
- : type(DIT_FLOAT_CONST)
- , float_const(val)
- {
- }
- dump_item(TString& val)
- : type(DIT_STR_CONST)
- , the_buf(val)
- {
- }
-
- dump_item(int_fn_t fn)
- : type(DIT_INT_FUNCTION)
- , int_fn(fn)
- {
- }
- dump_item(float_fn_t fn)
- : type(DIT_FLOAT_FUNCTION)
- , float_fn(fn)
- {
- }
- dump_item(bool_fn_t fn)
- : type(DIT_BOOL_FUNCTION)
- , bool_fn(fn)
- {
- }
- dump_item(bool_strbuf_fn_t fn, const char* name)
- : type(DIT_BOOL_FUNC_FIXED_STR)
- , bool_strbuf_fn(fn)
- , the_buf(name)
- {
- }
- dump_item(ui8_strbuf_fn_t fn, const char* name)
- : type(DIT_UI8_FUNC_FIXED_STR)
- , ui8_strbuf_fn(fn)
- , the_buf(name)
- {
- }
- dump_item(ui16_strbuf_fn_t fn, const char* name)
- : type(DIT_UI16_FUNC_FIXED_STR)
- , ui16_strbuf_fn(fn)
- , the_buf(name)
- {
- }
- dump_item(ui32_strbuf_fn_t fn, const char* name)
- : type(DIT_UI32_FUNC_FIXED_STR)
- , ui32_strbuf_fn(fn)
- , the_buf(name)
- {
- }
- dump_item(i64_strbuf_fn_t fn, const char* name)
- : type(DIT_I64_FUNC_FIXED_STR)
- , i64_strbuf_fn(fn)
- , the_buf(name)
- {
- }
- dump_item(ui64_strbuf_fn_t fn, const char* name)
- : type(DIT_UI64_FUNC_FIXED_STR)
- , ui64_strbuf_fn(fn)
- , the_buf(name)
- {
- }
- dump_item(float_strbuf_fn_t fn, const char* name)
- : type(DIT_FLOAT_FUNC_FIXED_STR)
- , float_strbuf_fn(fn)
- , the_buf(name)
- {
- }
- dump_item(double_strbuf_fn_t fn, const char* name)
- : type(DIT_DOUBLE_FUNC_FIXED_STR)
- , double_strbuf_fn(fn)
- , the_buf(name)
- {
- }
- dump_item(str_fn_t fn)
- : type(DIT_STR_FUNCTION)
- , str_fn(fn)
- {
- }
- dump_item(strbuf_2_fn_t fn)
- : type(DIT_STRBUF_FUNCTION)
- , strbuf_2_fn(fn)
- {
- }
-
- dump_item(ui8_ext_fn_t fn, const char* lvn = nullptr)
- : type(DIT_UI8_EXT_FUNCTION)
- , ui8_ext_fn(fn)
- , local_var_name(lvn)
- {
- }
- dump_item(ui16_ext_fn_t fn, const char* lvn = nullptr)
- : type(DIT_UI16_EXT_FUNCTION)
- , ui16_ext_fn(fn)
- , local_var_name(lvn)
- {
- }
- dump_item(ui32_ext_fn_t fn, const char* lvn = nullptr)
- : type(DIT_UI32_EXT_FUNCTION)
- , ui32_ext_fn(fn)
- , local_var_name(lvn)
- {
- }
- dump_item(ui64_ext_fn_t fn, const char* lvn = nullptr)
- : type(DIT_UI64_EXT_FUNCTION)
- , ui64_ext_fn(fn)
- , local_var_name(lvn)
- {
- }
-
- dump_item(ui8* ptr, ui32 val, bool bitset)
- : type(bitset ? DIT_UI8_ENUM_SET : DIT_UI8_ENUM_EQ)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , enum_val(val)
- {
- }
-
- dump_item(ui16* ptr, ui32 val, bool bitset)
- : type(bitset ? DIT_UI16_ENUM_SET : DIT_UI16_ENUM_EQ)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , enum_val(val)
- {
- }
-
- dump_item(ui32* ptr, ui32 val, bool bitset)
- : type(bitset ? DIT_UI32_ENUM_SET : DIT_UI32_ENUM_EQ)
- , field_offset(reinterpret_cast<intptr_t>(ptr))
- , enum_val(val)
- {
- }
-
- dump_item(int_fn_t fn, ui32 val, bool bitset)
- : type(bitset ? DIT_INT_ENUM_FUNCTION_SET : DIT_INT_ENUM_FUNCTION_EQ)
- , int_enum_fn(fn)
- , enum_val(val)
- {
- }
-
- dump_item(resolve_fn_t fn, const char* name)
- : type(DIT_RESOLVE_BY_NAME)
- , resolve_fn(fn)
- , the_buf(name)
- {
- } //name of variable saved in the_buf
-
- // Functions
- template <class TOut> // implemented for FILE*, TString* (appends) and IOutputStream*
- void print(TOut* p, const char** dd) const;
- TStringBuf GetStrBuf(const char** dd) const; // for char-types only!
- eval_res_type eval(const char** dd) const;
- void set_arrind(int arrind);
- void rewrite_op(const calc_op* ops);
-
- bool is_accessor_func() const {
- return type >= DIT_INT_FUNCTION && type <= DIT_UI64_EXT_FUNCTION && local_var_name;
- }
-
- bool is_field() const {
- return type > DIT_FIELDS_START && type < DIT_FIELDS_END || is_accessor_func();
- }
-
- bool is_array_field() const {
- return is_field() && arr_length > 0;
- }
-};
-
-// named_dump_item
-struct named_dump_item {
- const char* name;
- dump_item item;
-};
diff --git a/library/cpp/fieldcalc/lossy_types.h b/library/cpp/fieldcalc/lossy_types.h
deleted file mode 100644
index 98acfea902..0000000000
--- a/library/cpp/fieldcalc/lossy_types.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-#include <util/generic/cast.h>
-
-// although target value is float, this thing is only used as unsigned int container
-struct pf16ui32 {
- ui16 val;
- pf16ui32()
- : val(0)
- {
- }
- void operator=(ui32 t) {
- val = static_cast<ui16>(BitCast<ui32>(static_cast<float>(t)) >> 15);
- }
- operator ui32() const {
- return (ui32)BitCast<float>((ui32)(val << 15));
- }
-};
-
-// unsigned float value
-struct pf16float {
- ui16 val;
- pf16float()
- : val(0)
- {
- }
- void operator=(float t) {
- assert(t >= 0.);
- val = static_cast<ui16>(BitCast<ui32>(t) >> 15);
- }
- operator float() const {
- return BitCast<float>((ui32)(val << 15));
- }
-};
-
-// signed float value
-struct sf16float {
- ui16 val;
- sf16float()
- : val(0)
- {
- }
- void operator=(float t) {
- assert(t >= 0.);
- val = BitCast<ui32>(t) >> 16;
- }
- operator float() const {
- return BitCast<float>((ui32)(val << 16));
- }
-};
-
-typedef i32 time_t32; // not really lossy, should be placed somewhere else
diff --git a/library/cpp/fieldcalc/ya.make b/library/cpp/fieldcalc/ya.make
deleted file mode 100644
index 9796592996..0000000000
--- a/library/cpp/fieldcalc/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-LIBRARY()
-
-PEERDIR(
- library/cpp/deprecated/autoarray
-)
-
-SRCS(
- field_calc.cpp
- lossy_types.h
- field_calc_int.h
-)
-
-END()
diff --git a/library/cpp/malloc/galloc/malloc-info.cpp b/library/cpp/malloc/galloc/malloc-info.cpp
deleted file mode 100644
index fbcfa7ee06..0000000000
--- a/library/cpp/malloc/galloc/malloc-info.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <library/cpp/malloc/api/malloc.h>
-
-using namespace NMalloc;
-
-TMallocInfo NMalloc::MallocInfo() {
- TMallocInfo r;
- r.Name = "tcmalloc";
- return r;
-}
diff --git a/library/cpp/malloc/galloc/ya.make b/library/cpp/malloc/galloc/ya.make
deleted file mode 100644
index b6646a6cf6..0000000000
--- a/library/cpp/malloc/galloc/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-LIBRARY()
-
-NO_UTIL()
-ALLOCATOR_IMPL()
-
-PEERDIR(
- library/cpp/malloc/api
- contrib/deprecated/galloc
-)
-
-SRCS(
- malloc-info.cpp
-)
-
-END()
diff --git a/library/cpp/on_disk/multi_blob/multiblob.cpp b/library/cpp/on_disk/multi_blob/multiblob.cpp
deleted file mode 100644
index d92b31e613..0000000000
--- a/library/cpp/on_disk/multi_blob/multiblob.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <util/generic/yexception.h>
-#include <util/system/align.h>
-
-#include <library/cpp/on_disk/chunks/reader.h>
-
-#include "multiblob.h"
-
-void TSubBlobs::ReadMultiBlob(const TBlob& multi) {
- if (multi.Size() < sizeof(TMultiBlobHeader)) {
- ythrow yexception() << "not a blob, too small";
- }
-
- Multi = multi;
- memcpy((void*)&Header, Multi.Data(), sizeof(TMultiBlobHeader));
-
- if (Header.BlobMetaSig != BLOBMETASIG) {
- if (Header.BlobRecordSig != TMultiBlobHeader::RecordSig) {
- if (ReadChunkedData(multi))
- return;
- }
- ythrow yexception() << "is not a blob, MetaSig was read: "
- << Header.BlobMetaSig
- << ", must be" << BLOBMETASIG;
- }
-
- if (Header.BlobRecordSig != TMultiBlobHeader::RecordSig)
- ythrow yexception() << "unknown multiblob RecordSig "
- << Header.BlobRecordSig;
-
- reserve(size() + Header.Count);
- if (Header.Flags & EMF_INTERLAY) {
- size_t pos = Header.HeaderSize();
- for (size_t i = 0; i < Header.Count; ++i) {
- pos = AlignUp<ui64>(pos, sizeof(ui64));
- ui64 size = *((ui64*)((const char*)multi.Data() + pos));
- pos = AlignUp<ui64>(pos + sizeof(ui64), Header.Align);
- push_back(multi.SubBlob(pos, pos + size));
- pos += size;
- }
- } else {
- const ui64* sizes = Header.Sizes(multi.Data());
- size_t pos = Header.HeaderSize() + Header.Count * sizeof(ui64);
- for (size_t i = 0; i < Header.Count; ++i) {
- pos = AlignUp<ui64>(pos, Header.Align);
- push_back(multi.SubBlob(pos, pos + *sizes));
- pos += *sizes;
- sizes++;
- }
- }
-}
-
-bool TSubBlobs::ReadChunkedData(const TBlob& multi) noexcept {
- Multi = multi;
- memset((void*)&Header, 0, sizeof(Header));
-
- TChunkedDataReader reader(Multi);
- Header.Count = reader.GetBlocksCount();
- resize(GetHeader()->Count);
- for (size_t i = 0; i < size(); ++i)
- // We can use TBlob::NoCopy() because of reader.GetBlock(i) returns
- // address into memory of multi blob.
- // This knowledge was acquired from implementation of
- // TChunkedDataReader, so we need care about any changes that.
- (*this)[i] = TBlob::NoCopy(reader.GetBlock(i), reader.GetBlockLen(i));
- Header.Flags |= EMF_CHUNKED_DATA_READER;
- return true;
-}
diff --git a/library/cpp/on_disk/multi_blob/multiblob.h b/library/cpp/on_disk/multi_blob/multiblob.h
deleted file mode 100644
index b40a5ae6af..0000000000
--- a/library/cpp/on_disk/multi_blob/multiblob.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#pragma once
-
-#include <util/generic/vector.h>
-#include <util/memory/blob.h>
-
-#define BLOBMETASIG 0x3456789Au
-
-enum E_Multiblob_Flags {
- // if EMF_INTERLAY is clear
- // multiblob format
- // HeaderSize() bytes for TMultiBlobHeader
- // Count*sizeof(ui64) bytes for blob sizes
- // blob1
- // (alignment)
- // blob2
- // (alignment)
- // ...
- // (alignment)
- // blobn
- // if EMF_INTERLAY is set
- // multiblob format
- // HeaderSize() bytes for TMultiBlobHeader
- // size1 ui64, the size of 1st blob
- // blob1
- // (alignment)
- // size2 ui64, the size of 2nd blob
- // blob2
- // (alignment)
- // ...
- // (alignment)
- // sizen ui64, the size of n'th blob
- // blobn
- EMF_INTERLAY = 1,
-
- // Means that multiblob contains blocks in TChunkedDataReader format
- // Legacy, use it only for old files, created for TChunkedDataReader
- EMF_CHUNKED_DATA_READER = 2,
-
- // Flags that may be configured for blobbuilder in client code
- EMF_WRITEABLE = EMF_INTERLAY,
-};
-
-struct TMultiBlobHeader {
- // data
- ui32 BlobMetaSig;
- ui32 BlobRecordSig;
- ui64 Count; // count of sub blobs
- ui32 Align; // alignment for every subblob
- ui32 Flags;
- static const ui32 RecordSig = 0x23456789;
- static inline size_t HeaderSize() {
- return 4 * sizeof(ui64);
- }
- inline const ui64* Sizes(const void* Data) const {
- return (const ui64*)((const char*)Data + HeaderSize());
- }
-};
-
-class TSubBlobs: public TVector<TBlob> {
-public:
- TSubBlobs() {
- }
- TSubBlobs(const TBlob& multi) {
- ReadMultiBlob(multi);
- }
- void ReadMultiBlob(const TBlob& multi);
- const TMultiBlobHeader* GetHeader() const {
- return (const TMultiBlobHeader*)&Header;
- }
-
-protected:
- TMultiBlobHeader Header;
- TBlob Multi;
-
-private:
- bool ReadChunkedData(const TBlob& multi) noexcept;
-};
diff --git a/library/cpp/on_disk/multi_blob/multiblob_builder.cpp b/library/cpp/on_disk/multi_blob/multiblob_builder.cpp
deleted file mode 100644
index 44aa4a6c2f..0000000000
--- a/library/cpp/on_disk/multi_blob/multiblob_builder.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-#include <util/memory/tempbuf.h>
-#include <util/system/align.h>
-
-#include "multiblob_builder.h"
-
-/*
- * TBlobSaverMemory
- */
-TBlobSaverMemory::TBlobSaverMemory(const void* ptr, size_t size)
- : Blob(TBlob::NoCopy(ptr, size))
-{
-}
-
-TBlobSaverMemory::TBlobSaverMemory(const TBlob& blob)
- : Blob(blob)
-{
-}
-
-void TBlobSaverMemory::Save(IOutputStream& output, ui32 /*flags*/) {
- output.Write((void*)Blob.Data(), Blob.Length());
-}
-
-size_t TBlobSaverMemory::GetLength() {
- return Blob.Length();
-}
-
-/*
- * TBlobSaverFile
- */
-
-TBlobSaverFile::TBlobSaverFile(TFile file)
- : File(file)
-{
- Y_ASSERT(File.IsOpen());
-}
-
-TBlobSaverFile::TBlobSaverFile(const char* filename, EOpenMode oMode)
- : File(filename, oMode)
-{
- Y_ASSERT(File.IsOpen());
-}
-
-void TBlobSaverFile::Save(IOutputStream& output, ui32 /*flags*/) {
- TTempBuf buffer(1 << 20);
- while (size_t size = File.Read((void*)buffer.Data(), buffer.Size()))
- output.Write((void*)buffer.Data(), size);
-}
-
-size_t TBlobSaverFile::GetLength() {
- return File.GetLength();
-}
-
-/*
- * TMultiBlobBuilder
- */
-
-TMultiBlobBuilder::TMultiBlobBuilder(bool isOwn)
- : IsOwner(isOwn)
-{
-}
-
-TMultiBlobBuilder::~TMultiBlobBuilder() {
- if (IsOwner)
- DeleteSubBlobs();
-}
-
-namespace {
- ui64 PadToAlign(IOutputStream& output, ui64 fromPos, ui32 align) {
- ui64 toPos = AlignUp<ui64>(fromPos, align);
- for (; fromPos < toPos; ++fromPos) {
- output << (char)0;
- }
- return toPos;
- }
-}
-
-void TMultiBlobBuilder::Save(IOutputStream& output, ui32 flags) {
- TMultiBlobHeader header;
- memset((void*)&header, 0, sizeof(header));
- header.BlobMetaSig = BLOBMETASIG;
- header.BlobRecordSig = TMultiBlobHeader::RecordSig;
- header.Count = Blobs.size();
- header.Align = ALIGN;
- header.Flags = flags & EMF_WRITEABLE;
- output.Write((void*)&header, sizeof(header));
- for (size_t i = sizeof(header); i < header.HeaderSize(); ++i)
- output << (char)0;
- ui64 pos = header.HeaderSize();
- if (header.Flags & EMF_INTERLAY) {
- for (size_t i = 0; i < Blobs.size(); ++i) {
- ui64 size = Blobs[i]->GetLength();
- pos = PadToAlign(output, pos, sizeof(ui64)); // Align size record
- output.Write((void*)&size, sizeof(ui64));
- pos = PadToAlign(output, pos + sizeof(ui64), header.Align); // Align blob
- Blobs[i]->Save(output, header.Flags);
- pos += size;
- }
- } else {
- for (size_t i = 0; i < Blobs.size(); ++i) {
- ui64 size = Blobs[i]->GetLength();
- output.Write((void*)&size, sizeof(ui64));
- }
- pos += Blobs.size() * sizeof(ui64);
- for (size_t i = 0; i < Blobs.size(); ++i) {
- pos = PadToAlign(output, pos, header.Align);
- Blobs[i]->Save(output, header.Flags);
- pos += Blobs[i]->GetLength();
- }
- }
- // Compensate for imprecise size
- for (ui64 len = GetLength(); pos < len; ++pos) {
- output << (char)0;
- }
-}
-
-size_t TMultiBlobBuilder::GetLength() {
- // Sizes may be diferent with and without EMF_INTERLAY, so choose greater of 2
- size_t resNonInter = TMultiBlobHeader::HeaderSize() + Blobs.size() * sizeof(ui64);
- size_t resInterlay = TMultiBlobHeader::HeaderSize();
- for (size_t i = 0; i < Blobs.size(); ++i) {
- resInterlay = AlignUp<ui64>(resInterlay, sizeof(ui64)) + sizeof(ui64);
- resInterlay = AlignUp<ui64>(resInterlay, ALIGN) + Blobs[i]->GetLength();
- resNonInter = AlignUp<ui64>(resNonInter, ALIGN) + Blobs[i]->GetLength();
- }
- resInterlay = AlignUp<ui64>(resInterlay, ALIGN);
- resNonInter = AlignUp<ui64>(resNonInter, ALIGN);
- return Max(resNonInter, resInterlay);
-}
-
-TMultiBlobBuilder::TSavers& TMultiBlobBuilder::GetBlobs() {
- return Blobs;
-}
-
-const TMultiBlobBuilder::TSavers& TMultiBlobBuilder::GetBlobs() const {
- return Blobs;
-}
-
-void TMultiBlobBuilder::AddBlob(IBlobSaverBase* blob) {
- Blobs.push_back(blob);
-}
-
-void TMultiBlobBuilder::DeleteSubBlobs() {
- for (size_t i = 0; i < Blobs.size(); ++i)
- delete Blobs[i];
- Blobs.clear();
-}
diff --git a/library/cpp/on_disk/multi_blob/multiblob_builder.h b/library/cpp/on_disk/multi_blob/multiblob_builder.h
deleted file mode 100644
index a8e3c6d35e..0000000000
--- a/library/cpp/on_disk/multi_blob/multiblob_builder.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#pragma once
-
-#include <util/system/align.h>
-#include <util/stream/output.h>
-#include <util/stream/file.h>
-#include <util/draft/holder_vector.h>
-
-#include "multiblob.h"
-
-class IBlobSaverBase {
-public:
- virtual ~IBlobSaverBase() {
- }
- virtual void Save(IOutputStream& output, ui32 flags = 0) = 0;
- virtual size_t GetLength() = 0;
-};
-
-inline void MultiBlobSave(IOutputStream& output, IBlobSaverBase& saver) {
- saver.Save(output);
-}
-
-class TBlobSaverMemory: public IBlobSaverBase {
-public:
- TBlobSaverMemory(const void* ptr, size_t size);
- TBlobSaverMemory(const TBlob& blob);
- void Save(IOutputStream& output, ui32 flags = 0) override;
- size_t GetLength() override;
-
-private:
- TBlob Blob;
-};
-
-class TBlobSaverFile: public IBlobSaverBase {
-public:
- TBlobSaverFile(TFile file);
- TBlobSaverFile(const char* filename, EOpenMode oMode = RdOnly);
- void Save(IOutputStream& output, ui32 flags = 0) override;
- size_t GetLength() override;
-
-protected:
- TFile File;
-};
-
-class TMultiBlobBuilder: public IBlobSaverBase {
-protected:
- // Data will be stored with default alignment DEVTOOLS-4548
- static const size_t ALIGN = 16;
-
-public:
- typedef TVector<IBlobSaverBase*> TSavers;
-
- TMultiBlobBuilder(bool isOwn = true);
- ~TMultiBlobBuilder() override;
- void Save(IOutputStream& output, ui32 flags = 0) override;
- size_t GetLength() override;
- TSavers& GetBlobs();
- const TSavers& GetBlobs() const;
- void AddBlob(IBlobSaverBase* blob);
- void DeleteSubBlobs();
-
-protected:
- TSavers Blobs;
- bool IsOwner;
-};
diff --git a/library/cpp/on_disk/multi_blob/ya.make b/library/cpp/on_disk/multi_blob/ya.make
deleted file mode 100644
index 50615fc901..0000000000
--- a/library/cpp/on_disk/multi_blob/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-LIBRARY()
-
-SRCS(
- multiblob.cpp
- multiblob_builder.cpp
-)
-
-PEERDIR(
- library/cpp/on_disk/chunks
- util/draft
-)
-
-END()
diff --git a/library/cpp/on_disk/st_hash/fake.cpp b/library/cpp/on_disk/st_hash/fake.cpp
deleted file mode 100644
index ef5af4d432..0000000000
--- a/library/cpp/on_disk/st_hash/fake.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "save_stl.h"
-#include "static_hash.h"
-#include "static_hash_map.h"
-#include "sthash_iterators.h"
diff --git a/library/cpp/on_disk/st_hash/save_stl.h b/library/cpp/on_disk/st_hash/save_stl.h
deleted file mode 100644
index 00f8f0e20d..0000000000
--- a/library/cpp/on_disk/st_hash/save_stl.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#pragma once
-
-#include <util/generic/hash.h>
-#include <util/system/yassert.h>
-#include <util/stream/output.h>
-
-// this structure might be replaced with sthashtable class
-template <class HF, class Eq, class size_type>
-struct sthashtable_nvm_sv {
- sthashtable_nvm_sv() {
- if (sizeof(sthashtable_nvm_sv) != sizeof(HF) + sizeof(Eq) + 3 * sizeof(size_type)) {
- memset(this, 0, sizeof(sthashtable_nvm_sv));
- }
- }
-
- sthashtable_nvm_sv(const HF& phf, const Eq& peq, const size_type& pnb, const size_type& pne, const size_type& pnd)
- : sthashtable_nvm_sv()
- {
- hf = phf;
- eq = peq;
- num_buckets = pnb;
- num_elements = pne;
- data_end_off = pnd;
- }
-
- HF hf;
- Eq eq;
- size_type num_buckets;
- size_type num_elements;
- size_type data_end_off;
-};
-
-/**
- * Some hack to save both THashMap and sthash.
- * Working with stHash does not depend on the template parameters, because the content of stHash is not used inside this method.
- */
-template <class V, class K, class HF, class Ex, class Eq, class A>
-template <class KeySaver>
-inline int THashTable<V, K, HF, Ex, Eq, A>::save_for_st(IOutputStream* stream, KeySaver& ks, sthash<int, int, THash<int>, TEqualTo<int>, typename KeySaver::TSizeType>* stHash) const {
- Y_ASSERT(!stHash || stHash->bucket_count() == bucket_count());
- typedef sthashtable_nvm_sv<HF, Eq, typename KeySaver::TSizeType> sv_type;
- sv_type sv = {this->_get_hash_fun(), this->_get_key_eq(), static_cast<typename KeySaver::TSizeType>(buckets.size()), static_cast<typename KeySaver::TSizeType>(num_elements), 0};
- // to do: m.b. use just the size of corresponding object?
- typename KeySaver::TSizeType cur_off = sizeof(sv_type) +
- (sv.num_buckets + 1) * sizeof(typename KeySaver::TSizeType);
- sv.data_end_off = cur_off;
- const_iterator n;
- for (n = begin(); n != end(); ++n) {
- sv.data_end_off += static_cast<typename KeySaver::TSizeType>(ks.GetRecordSize(*n));
- }
- typename KeySaver::TSizeType* sb = stHash ? (typename KeySaver::TSizeType*)(stHash->buckets()) : nullptr;
- if (stHash)
- sv.data_end_off += static_cast<typename KeySaver::TSizeType>(sb[buckets.size()] - sb[0]);
- //saver.Align(sizeof(char*));
- stream->Write(&sv, sizeof(sv));
-
- size_type i;
- //save vector
- for (i = 0; i < buckets.size(); ++i) {
- node* cur = buckets[i];
- stream->Write(&cur_off, sizeof(cur_off));
- if (cur) {
- while (!((uintptr_t)cur & 1)) {
- cur_off += static_cast<typename KeySaver::TSizeType>(ks.GetRecordSize(cur->val));
- cur = cur->next;
- }
- }
- if (stHash)
- cur_off += static_cast<typename KeySaver::TSizeType>(sb[i + 1] - sb[i]);
- }
- stream->Write(&cur_off, sizeof(cur_off)); // end mark
- for (i = 0; i < buckets.size(); ++i) {
- node* cur = buckets[i];
- if (cur) {
- while (!((uintptr_t)cur & 1)) {
- ks.SaveRecord(stream, cur->val);
- cur = cur->next;
- }
- }
- if (stHash)
- stream->Write((const char*)stHash + sb[i], sb[i + 1] - sb[i]);
- }
- return 0;
-}
diff --git a/library/cpp/on_disk/st_hash/static_hash.h b/library/cpp/on_disk/st_hash/static_hash.h
deleted file mode 100644
index ca7a6ccd36..0000000000
--- a/library/cpp/on_disk/st_hash/static_hash.h
+++ /dev/null
@@ -1,420 +0,0 @@
-#pragma once
-
-#include "save_stl.h"
-#include "sthash_iterators.h"
-
-#include <util/generic/hash.h>
-#include <util/generic/vector.h>
-#include <util/generic/buffer.h>
-#include <util/generic/cast.h>
-#include <util/generic/yexception.h> // for save/load only
-#include <util/stream/file.h>
-#include <util/stream/buffer.h>
-#include <utility>
-
-#include <memory>
-#include <algorithm>
-#include <functional>
-
-#include <cstdlib>
-#include <cstddef>
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4624) // 'destructor could not be generated because a base class destructor is inaccessible'
-#endif
-
-template <class HashType, class KeySaver>
-inline void SaveHashToStreamEx(HashType& hash, IOutputStream* stream) {
- KeySaver ks;
- if (hash.save_for_st(stream, ks))
- ythrow yexception() << "Could not save hash to stream";
-}
-
-template <class HashType>
-inline void SaveHashToStream(HashType& hash, IOutputStream* stream) {
- typedef TSthashWriter<typename HashType::key_type, typename HashType::mapped_type, ui64> KeySaver;
- return SaveHashToStreamEx<HashType, KeySaver>(hash, stream);
-}
-
-template <class HashType, class KeySaver>
-inline void SaveHashToFileEx(HashType& hash, const char* fileName) {
- TFileOutput output(fileName);
- SaveHashToStreamEx<HashType, KeySaver>(hash, &output);
-}
-
-template <class HashType>
-inline void SaveHashToFile(HashType& hash, const char* fileName) {
- typedef TSthashWriter<typename HashType::key_type, typename HashType::mapped_type, ui64> KeySaver;
- return SaveHashToFileEx<HashType, KeySaver>(hash, fileName);
-}
-
-template <class HashType>
-inline void SaveHashSetToFile(HashType& hash, const char* fileName) {
- typedef TSthashSetWriter<typename HashType::key_type, ui64> KeySaver;
- return SaveHashToFileEx<HashType, KeySaver>(hash, fileName);
-}
-
-template <class HashType>
-inline void SaveHashToFile32(HashType& hash, const char* fileName) {
- typedef TSthashWriter<typename HashType::key_type, typename HashType::mapped_type, ui32> KeySaver;
- return SaveHashToFileEx<HashType, KeySaver>(hash, fileName);
-}
-
-template <class HashType, class KeySaver>
-inline void SaveHashToBufferEx(HashType& hash, TBuffer& buffer, sthash<int, int, THash<int>, TEqualTo<int>, typename KeySaver::TSizeType>* stHash = nullptr) {
- TBufferOutput stream(buffer);
- KeySaver ks;
- if (hash.save_for_st(&stream, ks, stHash))
- ythrow yexception() << "Could not save hash to memory";
-}
-
-template <class HashType>
-inline void SaveHashToBuffer(HashType& hash, TBuffer& buffer) {
- typedef TSthashWriter<typename HashType::key_type, typename HashType::mapped_type, ui64> KeySaver;
- SaveHashToBufferEx<HashType, KeySaver>(hash, buffer);
-}
-
-/**
- * Some hack to save both THashMap and sthash.
- * THashMap and sthash must have same bucket_count().
- */
-template <class HashType, class StHashType>
-inline void SaveHashToBuffer(HashType& hash, TBuffer& buffer, StHashType* stHash) {
- typedef TSthashWriter<typename HashType::key_type, typename HashType::mapped_type, ui64> KeySaver;
- typedef sthash<int, int, THash<int>, TEqualTo<int>, typename KeySaver::TSizeType>* SH;
-
- SH sh = reinterpret_cast<SH>(stHash);
- SaveHashToBufferEx<HashType, KeySaver>(hash, buffer, sh);
-}
-
-template <class HashType>
-inline void SaveHashToBuffer32(HashType& hash, TBuffer& buffer) {
- typedef TSthashWriter<typename HashType::key_type, typename HashType::mapped_type, ui32> KeySaver;
- SaveHashToBufferEx<HashType, KeySaver>(hash, buffer);
-}
-
-template <class Iter, typename size_type_f = ui64>
-class sthashtable {
-public:
- typedef typename Iter::TKeyType key_type;
- typedef typename Iter::TValueType value_type;
- typedef typename Iter::THasherType hasher;
- typedef typename Iter::TKeyEqualType key_equal;
-
- typedef size_type_f size_type;
- typedef ptrdiff_t difference_type;
- typedef const value_type* const_pointer;
- typedef const value_type& const_reference;
-
- typedef Iter const_iterator;
-
- const hasher hash_funct() const {
- return hash;
- }
- const key_equal key_eq() const {
- return equals;
- }
-
-private:
- const hasher hash;
- const key_equal equals;
-
-private:
- const_iterator iter_at_bucket(size_type bucket) const {
- return (const_iterator)(((char*)this + buckets()[bucket]));
- }
-
- const_iterator iter_at_bucket_or_end(size_type bucket) const {
- if (bucket < num_buckets)
- return (const_iterator)(((char*)this + buckets()[bucket]));
- else
- return end();
- }
-
- const size_type num_buckets;
- const size_type num_elements;
- const size_type data_end_off;
-
-protected: //shut up gcc warning
- // we can't construct/destroy this object at all!
- sthashtable();
- sthashtable(const sthashtable& ht);
- ~sthashtable();
-
-public:
- // const size_type *buckets;
- const size_type* buckets() const {
- return (size_type*)((char*)this + sizeof(*this));
- }
- const size_type buckets(size_type n) const {
- return buckets()[n];
- }
-
- size_type size() const {
- return num_elements;
- }
- size_type max_size() const {
- return size_type(-1);
- }
- bool empty() const {
- return size() == 0;
- }
-
- const_iterator begin() const {
- return num_buckets ? iter_at_bucket(0) : end();
- }
-
- const_iterator end() const {
- return (const_iterator)(((char*)this + data_end_off));
- }
-
-public:
- size_type size_in_bytes() const {
- return data_end_off;
- }
-
- size_type bucket_count() const {
- return num_buckets;
- }
-
- size_type elems_in_bucket(size_type bucket) const {
- size_type result = 0;
- const_iterator first = iter_at_bucket(bucket);
- const_iterator last = iter_at_bucket_or_end(bucket + 1);
-
- for (; first != last; ++first)
- ++result;
- return result;
- }
-
- template <class TheKey>
- const_iterator find(const TheKey& key) const {
- size_type n = bkt_num_key(key);
- const_iterator first(iter_at_bucket(n)), last(iter_at_bucket_or_end(n + 1));
- for (;
- first != last && !first.KeyEquals(equals, key);
- ++first) {
- }
- if (first != last)
- return first;
- return end();
- }
-
- size_type count(const key_type& key) const {
- const size_type n = bkt_num_key(key);
- size_type result = 0;
- const_iterator first = iter_at_bucket(n);
- const_iterator last = iter_at_bucket_or_end(n + 1);
-
- for (; first != last; ++first)
- if (first.KeyEquals(equals, key))
- ++result;
- return result;
- }
-
- std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const;
-
-private:
- template <class TheKey>
- size_type bkt_num_key(const TheKey& key) const {
- return hash(key) % num_buckets;
- }
-};
-
-template <class I, class size_type_f>
-std::pair<I, I> sthashtable<I, size_type_f>::equal_range(const key_type& key) const {
- typedef std::pair<const_iterator, const_iterator> pii;
- const size_type n = bkt_num_key(key);
- const_iterator first = iter_at_bucket(n);
- const_iterator last = iter_at_bucket_or_end(n + 1);
-
- for (; first != last; ++first) {
- if (first.KeyEquals(equals, key)) {
- const_iterator cur = first;
- ++cur;
- for (; cur != last; ++cur)
- if (!cur.KeyEquals(equals, key))
- return pii(const_iterator(first),
- const_iterator(cur));
- return pii(const_iterator(first),
- const_iterator(last));
- }
- }
- return pii(end(), end());
-}
-
-/* end __SGI_STL_HASHTABLE_H */
-
-template <class Key, class T, class HashFcn /*= hash<Key>*/,
- class EqualKey = TEqualTo<Key>, typename size_type_f = ui64>
-class sthash {
-private:
- typedef sthashtable<TSthashIterator<const Key, const T, HashFcn, EqualKey>, size_type_f> ht;
- ht rep;
-
-public:
- typedef typename ht::key_type key_type;
- typedef typename ht::value_type value_type;
- typedef typename ht::hasher hasher;
- typedef typename ht::key_equal key_equal;
- typedef T mapped_type;
-
- typedef typename ht::size_type size_type;
- typedef typename ht::difference_type difference_type;
- typedef typename ht::const_pointer const_pointer;
- typedef typename ht::const_reference const_reference;
-
- typedef typename ht::const_iterator const_iterator;
-
- const hasher hash_funct() const {
- return rep.hash_funct();
- }
- const key_equal key_eq() const {
- return rep.key_eq();
- }
-
-public:
- size_type size() const {
- return rep.size();
- }
- size_type max_size() const {
- return rep.max_size();
- }
- bool empty() const {
- return rep.empty();
- }
-
- const_iterator begin() const {
- return rep.begin();
- }
- const_iterator end() const {
- return rep.end();
- }
-
-public:
- template <class TheKey>
- const_iterator find(const TheKey& key) const {
- return rep.find(key);
- }
- template <class TheKey>
- bool has(const TheKey& key) const {
- return rep.find(key) != rep.end();
- }
-
- size_type count(const key_type& key) const {
- return rep.count(key);
- }
-
- std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
- return rep.equal_range(key);
- }
-
- size_type size_in_bytes() const {
- return rep.size_in_bytes();
- }
-
- size_type bucket_count() const {
- return rep.bucket_count();
- }
- size_type max_bucket_count() const {
- return rep.max_bucket_count();
- }
- size_type elems_in_bucket(size_type n) const {
- return rep.elems_in_bucket(n);
- }
-
- const size_type* buckets() const {
- return rep.buckets();
- }
- const size_type buckets(size_type n) const {
- return rep.buckets()[n];
- }
-};
-
-template <class Key, class HashFcn,
- class EqualKey = TEqualTo<Key>, typename size_type_f = ui64>
-class sthash_set: public sthash<Key, TEmptyValue, HashFcn, EqualKey, size_type_f> {
- typedef sthash<Key, TEmptyValue, HashFcn, EqualKey, size_type_f> Base;
-
-public:
- using Base::const_iterator;
- using Base::hasher;
- using Base::key_equal;
- using Base::key_type;
- using Base::size_type;
- using Base::value_type;
-};
-
-template <class Key, class T, class HashFcn /*= hash<Key>*/,
- class EqualKey = TEqualTo<Key>, typename size_type_f = ui64>
-class sthash_mm {
-private:
- typedef sthashtable<TSthashIterator<const Key, T, HashFcn, EqualKey>, size_type_f> ht;
- ht rep;
-
-public:
- typedef typename ht::key_type key_type;
- typedef typename ht::value_type value_type;
- typedef typename ht::hasher hasher;
- typedef typename ht::key_equal key_equal;
- typedef T mapped_type;
-
- typedef typename ht::size_type size_type;
- typedef typename ht::difference_type difference_type;
- typedef typename ht::const_pointer const_pointer;
- typedef typename ht::const_reference const_reference;
-
- typedef typename ht::const_iterator const_iterator;
-
- const hasher hash_funct() const {
- return rep.hash_funct();
- }
- const key_equal key_eq() const {
- return rep.key_eq();
- }
-
-public:
- size_type size() const {
- return rep.size();
- }
- size_type max_size() const {
- return rep.max_size();
- }
- bool empty() const {
- return rep.empty();
- }
-
- const_iterator begin() const {
- return rep.begin();
- }
- const_iterator end() const {
- return rep.end();
- }
-
- const_iterator find(const key_type& key) const {
- return rep.find(key);
- }
-
- size_type count(const key_type& key) const {
- return rep.count(key);
- }
-
- std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
- return rep.equal_range(key);
- }
-
- size_type bucket_count() const {
- return rep.bucket_count();
- }
- size_type max_bucket_count() const {
- return rep.max_bucket_count();
- }
- size_type elems_in_bucket(size_type n) const {
- return rep.elems_in_bucket(n);
- }
-};
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
diff --git a/library/cpp/on_disk/st_hash/static_hash_map.h b/library/cpp/on_disk/st_hash/static_hash_map.h
deleted file mode 100644
index 5dc50abd39..0000000000
--- a/library/cpp/on_disk/st_hash/static_hash_map.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#pragma once
-
-#include "static_hash.h"
-
-#include <library/cpp/deprecated/mapped_file/mapped_file.h>
-
-#include <util/system/filemap.h>
-
-template <class SH>
-struct sthash_mapped_c {
- typedef SH H;
- typedef typename H::const_iterator const_iterator;
- TMappedFile M;
- H* hsh;
- sthash_mapped_c()
- : M()
- , hsh(nullptr)
- {
- }
- sthash_mapped_c(const char* fname, bool precharge)
- : M()
- , hsh(nullptr)
- {
- Open(fname, precharge);
- }
- void Open(const char* fname, bool precharge) {
- M.init(fname);
- if (precharge)
- M.precharge();
- hsh = (H*)M.getData();
- if (M.getSize() < sizeof(H) || (ssize_t)M.getSize() != hsh->end().Data - (char*)hsh)
- ythrow yexception() << "Could not map hash: " << fname << " is damaged";
- }
- H* operator->() {
- return hsh;
- }
- const H* operator->() const {
- return hsh;
- }
- H* GetSthash() {
- return hsh;
- }
- const H* GetSthash() const {
- return hsh;
- }
-};
-
-template <class Key, class T, class Hash>
-struct sthash_mapped: public sthash_mapped_c<sthash<Key, T, Hash>> {
- typedef sthash<Key, T, Hash> H;
- sthash_mapped(const char* fname, bool precharge)
- : sthash_mapped_c<H>(fname, precharge)
- {
- }
- sthash_mapped()
- : sthash_mapped_c<H>()
- {
- }
-};
diff --git a/library/cpp/on_disk/st_hash/sthash_iterators.h b/library/cpp/on_disk/st_hash/sthash_iterators.h
deleted file mode 100644
index 6a9ebdd6c3..0000000000
--- a/library/cpp/on_disk/st_hash/sthash_iterators.h
+++ /dev/null
@@ -1,334 +0,0 @@
-#pragma once
-
-#include "save_stl.h"
-
-#include <util/system/align.h>
-
-/**
- This file provides functionality for saving some relatively simple THashMap object
- to disk in a form that can be mapped read-only (via mmap) at any address.
- That saved object is accessed via pointer to sthash object (that must have
- the same parameters as original THashMap object)
-
- If either key or value are variable-sized (i.e. contain pointers), user must
- write his own instantiation of TSthashIterator (read iterator for sthash) and
- TSthashWriter (write iterator for THashMap).
- An example for <const char *, B> pair is in here.
-**/
-
-// TEmptyValue and SizeOfEx are helpers for sthash_set
-struct TEmptyValue {
- TEmptyValue() = default;
-};
-
-template <class T>
-inline size_t SizeOfEx() {
- return sizeof(T);
-}
-
-template <>
-inline size_t SizeOfEx<TEmptyValue>() {
- return 0;
-}
-template <>
-inline size_t SizeOfEx<const TEmptyValue>() {
- return 0;
-}
-
-template <class TKey, class TValue, class HashFcn, class EqualKey>
-struct TSthashIterator {
- // Implementation for simple types
- typedef const TKey TKeyType;
- typedef const TValue TValueType;
- typedef EqualKey TKeyEqualType;
- typedef HashFcn THasherType;
-
- const char* Data;
- TSthashIterator()
- : Data(nullptr)
- {
- }
- explicit TSthashIterator(const char* data)
- : Data(data)
- {
- }
- void operator++() {
- Data += GetLength();
- }
-
- bool operator!=(const TSthashIterator& that) const {
- return Data != that.Data;
- }
- bool operator==(const TSthashIterator& that) const {
- return Data == that.Data;
- }
- TKey& Key() const {
- return *(TKey*)Data;
- }
- TValue& Value() {
- return *(TValue*)(Data + sizeof(TKey));
- }
- const TValue& Value() const {
- return *(const TValue*)(Data + sizeof(TKey));
- }
-
- template <class AnotherKeyType>
- bool KeyEquals(const EqualKey& eq, const AnotherKeyType& key) const {
- return eq(*(TKey*)Data, key);
- }
-
- size_t GetLength() const {
- return sizeof(TKey) + SizeOfEx<TValue>();
- }
-};
-
-template <class Key, class Value, typename size_type_o = ui64>
-struct TSthashWriter {
- typedef size_type_o TSizeType;
- size_t GetRecordSize(const std::pair<const Key, const Value>&) const {
- return sizeof(Key) + SizeOfEx<Value>();
- }
- int SaveRecord(IOutputStream* stream, const std::pair<const Key, const Value>& record) const {
- stream->Write(&record.first, sizeof(Key));
- stream->Write(&record.second, SizeOfEx<Value>());
- return 0;
- }
-};
-
-// Remember that this simplified implementation makes a copy of `key' in std::make_pair.
-// It can also waste some memory on undesired alignment.
-template <class Key, typename size_type_o = ui64>
-struct TSthashSetWriter: public TSthashWriter<Key, TEmptyValue, size_type_o> {
- typedef TSthashWriter<Key, TEmptyValue, size_type_o> MapWriter;
- size_t GetRecordSize(const Key& key) const {
- return MapWriter::GetRecordSize(std::make_pair(key, TEmptyValue()));
- }
- int SaveRecord(IOutputStream* stream, const Key& key) const {
- return MapWriter::SaveRecord(stream, std::make_pair(key, TEmptyValue()));
- }
-};
-
-// we can't save something with pointers without additional tricks
-
-template <class A, class B, class HashFcn, class EqualKey>
-struct TSthashIterator<A*, B, HashFcn, EqualKey> {};
-
-template <class A, class B, class HashFcn, class EqualKey>
-struct TSthashIterator<A, B*, HashFcn, EqualKey> {};
-
-template <class A, class B, typename size_type_o>
-struct TSthashWriter<A*, B*, size_type_o> {};
-
-template <class A, class B, typename size_type_o>
-struct TSthashWriter<A*, B, size_type_o> {};
-
-template <class A, class B, typename size_type_o>
-struct TSthashWriter<A, B*, size_type_o> {};
-
-template <class T>
-inline size_t AlignForChrKey() {
- return 4; // TODO: change this (requeres rebuilt of a few existing files)
-}
-
-template <>
-inline size_t AlignForChrKey<TEmptyValue>() {
- return 1;
-}
-
-template <>
-inline size_t AlignForChrKey<const TEmptyValue>() {
- return AlignForChrKey<TEmptyValue>();
-}
-
-// !! note that for char*, physical placement of key and value is swapped
-template <class TValue, class HashFcn, class EqualKey>
-struct TSthashIterator<const char* const, TValue, HashFcn, EqualKey> {
- typedef const TValue TValueType;
- typedef const char* TKeyType;
- typedef EqualKey TKeyEqualType;
- typedef HashFcn THasherType;
-
- const char* Data;
- TSthashIterator()
- : Data(nullptr)
- {
- }
- TSthashIterator(const char* data)
- : Data(data)
- {
- }
- void operator++() {
- Data += GetLength();
- }
-
- bool operator!=(const TSthashIterator& that) const {
- return Data != that.Data;
- }
- bool operator==(const TSthashIterator& that) const {
- return Data == that.Data;
- }
- const char* Key() const {
- return Data + SizeOfEx<TValue>();
- }
- TValue& Value() {
- return *(TValue*)Data;
- }
- const TValue& Value() const {
- return *(const TValue*)Data;
- }
-
- template <class K>
- bool KeyEquals(const EqualKey& eq, const K& k) const {
- return eq(Data + SizeOfEx<TValue>(), k);
- }
-
- size_t GetLength() const {
- size_t length = strlen(Data + SizeOfEx<TValue>()) + 1 + SizeOfEx<TValue>();
- length = AlignUp(length, AlignForChrKey<TValue>());
- return length;
- }
-};
-
-template <class Value, typename size_type_o>
-struct TSthashWriter<const char*, Value, size_type_o> {
- typedef size_type_o TSizeType;
- size_t GetRecordSize(const std::pair<const char*, const Value>& record) const {
- size_t length = strlen(record.first) + 1 + SizeOfEx<Value>();
- length = AlignUp(length, AlignForChrKey<Value>());
- return length;
- }
- int SaveRecord(IOutputStream* stream, const std::pair<const char*, const Value>& record) const {
- const char* alignBuffer = "qqqq";
- stream->Write(&record.second, SizeOfEx<Value>());
- size_t length = strlen(record.first) + 1;
- stream->Write(record.first, length);
- length = AlignUpSpace(length, AlignForChrKey<Value>());
- if (length)
- stream->Write(alignBuffer, length);
- return 0;
- }
-};
-
-template <class TKey, class HashFcn, class EqualKey>
-struct TSthashIterator<TKey, const char* const, HashFcn, EqualKey> {
- typedef const TKey TKeyType;
- typedef const char* TValueType;
- typedef EqualKey TKeyEqualType;
- typedef HashFcn THasherType;
-
- const char* Data;
- TSthashIterator()
- : Data(nullptr)
- {
- }
- TSthashIterator(const char* data)
- : Data(data)
- {
- }
- void operator++() {
- Data += GetLength();
- }
-
- bool operator!=(const TSthashIterator& that) const {
- return Data != that.Data;
- }
- bool operator==(const TSthashIterator& that) const {
- return Data == that.Data;
- }
- TKey& Key() {
- return *(TKey*)Data;
- }
- const char* Value() const {
- return Data + sizeof(TKey);
- }
-
- template <class K>
- bool KeyEquals(const EqualKey& eq, const K& k) const {
- return eq(*(TKey*)Data, k);
- }
-
- size_t GetLength() const {
- size_t length = strlen(Data + sizeof(TKey)) + 1 + sizeof(TKey);
- length = AlignUp(length, (size_t)4);
- return length;
- }
-};
-
-template <class Key, typename size_type_o>
-struct TSthashWriter<Key, const char*, size_type_o> {
- typedef size_type_o TSizeType;
- size_t GetRecordSize(const std::pair<const Key, const char*>& record) const {
- size_t length = strlen(record.second) + 1 + sizeof(Key);
- length = AlignUp(length, (size_t)4);
- return length;
- }
- int SaveRecord(IOutputStream* stream, const std::pair<const Key, const char*>& record) const {
- const char* alignBuffer = "qqqq";
- stream->Write(&record.first, sizeof(Key));
- size_t length = strlen(record.second) + 1;
- stream->Write(record.second, length);
- length = AlignUpSpace(length, (size_t)4);
- if (length)
- stream->Write(alignBuffer, length);
- return 0;
- }
-};
-
-template <class HashFcn, class EqualKey>
-struct TSthashIterator<const char* const, const char* const, HashFcn, EqualKey> {
- typedef const char* TKeyType;
- typedef const char* TValueType;
- typedef EqualKey TKeyEqualType;
- typedef HashFcn THasherType;
-
- const char* Data;
- TSthashIterator()
- : Data(nullptr)
- {
- }
- TSthashIterator(const char* data)
- : Data(data)
- {
- }
- void operator++() {
- Data += GetLength();
- }
-
- bool operator!=(const TSthashIterator& that) const {
- return Data != that.Data;
- }
- bool operator==(const TSthashIterator& that) const {
- return Data == that.Data;
- }
- const char* Key() const {
- return Data;
- }
- const char* Value() const {
- return Data + strlen(Data) + 1;
- }
-
- template <class K>
- bool KeyEquals(const EqualKey& eq, const K& k) const {
- return eq(Data, k);
- }
-
- size_t GetLength() const {
- size_t length = strlen(Data) + 1;
- length += strlen(Data + length) + 1;
- return length;
- }
-};
-
-template <typename size_type_o>
-struct TSthashWriter<const char*, const char*, size_type_o> {
- typedef size_type_o TSizeType;
- size_t GetRecordSize(const std::pair<const char*, const char*>& record) const {
- size_t size = strlen(record.first) + strlen(record.second) + 2;
- return size;
- }
- int SaveRecord(IOutputStream* stream, const std::pair<const char*, const char*>& record) const {
- stream->Write(record.first, strlen(record.first) + 1);
- stream->Write(record.second, strlen(record.second) + 1);
- return 0;
- }
-};
diff --git a/library/cpp/on_disk/st_hash/ya.make b/library/cpp/on_disk/st_hash/ya.make
deleted file mode 100644
index 8c6d05711c..0000000000
--- a/library/cpp/on_disk/st_hash/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-LIBRARY()
-
-SRCS(
- fake.cpp
- save_stl.h
- static_hash.h
- static_hash_map.h
- sthash_iterators.h
-)
-
-PEERDIR(
- library/cpp/deprecated/mapped_file
-)
-
-END()
diff --git a/library/cpp/remmap/remmap.cpp b/library/cpp/remmap/remmap.cpp
deleted file mode 100644
index ce72af7352..0000000000
--- a/library/cpp/remmap/remmap.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-#include <util/system/info.h>
-#include <util/system/defaults.h>
-
-#if defined(_win_)
-#include <util/system/winint.h>
-#elif defined(_unix_)
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#ifndef MAP_NOCORE
-#define MAP_NOCORE 0
-#endif
-#else
-#error todo
-#endif
-
-#include "remmap.h"
-
-static const size_t REMMAP_PAGESIZE = NSystemInfo::GetPageSize();
-
-#if defined(_unix_)
-TRemmapAllocation::TRemmapAllocation()
- : Ptr_(nullptr)
- , Size_(0)
-{
-}
-
-TRemmapAllocation::TRemmapAllocation(size_t size, char* base)
- : Ptr_(nullptr)
- , Size_(0)
-{
- Alloc(size, base);
-}
-
-char* TRemmapAllocation::Alloc(size_t size, char* base) {
- assert(Ptr_ == nullptr);
-
- if (!size)
- return nullptr;
-
- const size_t HUGESIZE = size_t(16) << 30;
- Ptr_ = CommonMMap(HUGESIZE, base);
-
- if (Ptr_ != (char*)MAP_FAILED)
- munmap((void*)Ptr_, HUGESIZE);
- else
- Ptr_ = nullptr;
-
- Ptr_ = CommonMMap(AlignUp(size, REMMAP_PAGESIZE), Ptr_);
- if (Ptr_ == (char*)MAP_FAILED)
- Ptr_ = nullptr;
-
- Size_ = Ptr_ ? size : 0;
- return Ptr_;
-}
-
-char* TRemmapAllocation::Realloc(size_t newsize) {
- if (Ptr_ == nullptr)
- return Alloc(newsize);
-
- size_t realSize = AlignUp(Size_, REMMAP_PAGESIZE);
- size_t needSize = AlignUp(newsize, REMMAP_PAGESIZE);
-
- if (needSize > realSize) {
- char* part = Ptr_ + realSize;
- char* bunch = CommonMMap(needSize - realSize, part);
- if (bunch != (char*)MAP_FAILED && bunch != part)
- munmap(bunch, needSize - realSize);
- if (bunch == (char*)MAP_FAILED || bunch != part)
- return FullRealloc(newsize);
- } else if (needSize < realSize)
- munmap(Ptr_ + needSize, realSize - needSize);
-
- if ((Size_ = newsize) == 0)
- Ptr_ = nullptr;
-
- return Ptr_;
-}
-
-void TRemmapAllocation::Dealloc() {
- if (Ptr_ != nullptr)
- munmap(Ptr_, AlignUp(Size_, REMMAP_PAGESIZE));
- Ptr_ = nullptr;
- Size_ = 0;
-}
-
-char* TRemmapAllocation::FullRealloc(size_t newsize) {
- char* newPtr = CommonMMap(newsize);
- Y_ABORT_UNLESS(newPtr != MAP_FAILED, "mmap failed");
-
- size_t useful = Min(Size_, newsize), cur = 0;
-
- for (; cur + REMMAP_PAGESIZE < useful; cur += REMMAP_PAGESIZE) {
- memcpy((void*)&newPtr[cur], (void*)&Ptr_[cur], REMMAP_PAGESIZE);
- munmap((void*)&Ptr_[cur], REMMAP_PAGESIZE);
- }
-
- memcpy((void*)&newPtr[cur], (void*)&Ptr_[cur], useful - cur);
- munmap((void*)&Ptr_[cur], AlignUp(Size_ - cur, REMMAP_PAGESIZE));
-
- Size_ = newsize;
- return (Ptr_ = newPtr);
-}
-
-inline char* TRemmapAllocation::CommonMMap(size_t size, char* base) {
- return (char*)mmap((void*)base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
-}
-
-#else
-TRemmapAllocation::TRemmapAllocation()
- : Allocation_(0, false, NULL)
-{
-}
-
-TRemmapAllocation::TRemmapAllocation(size_t size, char* base)
- : Allocation_(size, false, (void*)base)
-{
-}
-
-char* TRemmapAllocation::Alloc(size_t size, char* base) {
- return (char*)Allocation_.Alloc(size, (void*)base);
-}
-
-char* TRemmapAllocation::Realloc(size_t newsize) {
- return FullRealloc(newsize);
-}
-
-void TRemmapAllocation::Dealloc() {
- Allocation_.Dealloc();
-}
-
-char* TRemmapAllocation::FullRealloc(size_t newsize) {
- TMappedAllocation other(newsize);
- memcpy(other.Ptr(), Allocation_.Ptr(), Min(other.MappedSize(), Allocation_.MappedSize()));
- Allocation_.swap(other);
- return Data();
-}
-#endif
diff --git a/library/cpp/remmap/remmap.h b/library/cpp/remmap/remmap.h
deleted file mode 100644
index 7cb738f7ae..0000000000
--- a/library/cpp/remmap/remmap.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#pragma once
-
-#include <util/system/yassert.h>
-#include <util/system/align.h>
-#include <util/system/info.h>
-#include <util/system/filemap.h>
-#include <util/memory/alloc.h>
-#include <util/generic/noncopyable.h>
-
-class TRemmapAllocation : TNonCopyable {
-public:
- TRemmapAllocation();
- TRemmapAllocation(size_t size, char* base = nullptr);
-
- ~TRemmapAllocation() {
- Dealloc();
- }
-
- char* Alloc(size_t size, char* base = nullptr);
- char* Realloc(size_t newsize);
- void Dealloc();
- char* FullRealloc(size_t newsize);
-
-#if defined(_unix_)
-private:
- inline char* CommonMMap(size_t size, char* base = nullptr);
-
- char* Ptr_;
- size_t Size_;
-
-public:
- inline void* Ptr() const {
- return (void*)Ptr_;
- }
- inline char* Data(ui32 pos = 0) const {
- return Ptr_ + pos;
- }
- inline size_t Size() const {
- return Size_;
- }
- inline void swap(TRemmapAllocation& other) {
- DoSwap(Ptr_, other.Ptr_);
- DoSwap(Size_, other.Size_);
- }
-
-#else
-private:
- TMappedAllocation Allocation_;
-
-public:
- inline void* Ptr() const {
- return Allocation_.Ptr();
- }
- inline char* Data(ui32 pos = 0) const {
- return Allocation_.Data(pos);
- }
- inline size_t Size() const {
- return Allocation_.MappedSize();
- }
- inline void swap(TRemmapAllocation& other) {
- Allocation_.swap(other.Allocation_);
- }
-#endif
-};
diff --git a/library/cpp/remmap/ya.make b/library/cpp/remmap/ya.make
deleted file mode 100644
index 281df6443a..0000000000
--- a/library/cpp/remmap/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-LIBRARY()
-
-SRCS(
- remmap.cpp
-)
-
-END()
diff --git a/library/cpp/sqlite3/sqlite.cpp b/library/cpp/sqlite3/sqlite.cpp
deleted file mode 100644
index 98e498f76b..0000000000
--- a/library/cpp/sqlite3/sqlite.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-#include "sqlite.h"
-
-#include <util/generic/singleton.h>
-#include <util/generic/scope.h>
-
-#include <cstdlib>
-
-using namespace NSQLite;
-
-namespace {
- struct TSQLiteInit {
- inline TSQLiteInit() {
- int ret = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
-
- if (ret != SQLITE_OK) {
- ythrow TSQLiteError(ret) << "init failure";
- }
- }
-
- static inline void Ensure() {
- Singleton<TSQLiteInit>();
- }
- };
-}
-
-namespace NSQLite {
- TSQLiteError::TSQLiteError(sqlite3* hndl)
- : ErrorCode(sqlite3_errcode(hndl))
- {
- *this << sqlite3_errmsg(hndl) << ". ";
- }
-
- TSQLiteError::TSQLiteError(int rc)
- : ErrorCode(rc)
- {
- *this << sqlite3_errstr(rc) << " (" << rc << "). ";
- }
-
- TSQLiteDB::TSQLiteDB(const TString& path) {
- TSQLiteInit::Ensure();
-
- sqlite3* db = nullptr;
- const int rc = sqlite3_open(path.data(), &db);
-
- H_.Reset(db);
-
- if (rc) {
- ythrow TSQLiteError(Handle()) << "can not init db " << path.Quote();
- }
- }
-
- TSQLiteDB::TSQLiteDB(const TString& path, int flags) {
- TSQLiteInit::Ensure();
-
- sqlite3* db = nullptr;
- const int rc = sqlite3_open_v2(path.data(), &db, flags, nullptr);
-
- H_.Reset(db);
-
- if (rc) {
- ythrow TSQLiteError(Handle()) << "can not init db " << path.Quote();
- }
- }
-
- sqlite3* TSQLiteDB::Handle() const noexcept {
- return H_.Get();
- }
-
- size_t TSQLiteDB::RowsAffected() const noexcept {
- return static_cast<size_t>(sqlite3_changes(H_.Get()));
- }
-
- TSQLiteStatement::TSQLiteStatement(TSQLiteDB& db, const TString& s)
- : S_(s)
- {
- if (!S_.empty() && S_[S_.size() - 1] != ';') {
- S_ += ';';
- }
-
- sqlite3_stmt* st = nullptr;
- const char* tail = nullptr;
- const int rc = sqlite3_prepare_v2(db.Handle(), S_.data(), S_.size() + 1, &st, &tail);
-
- H_.Reset(st);
-
- if (rc != SQLITE_OK) {
- ythrow TSQLiteError(db.Handle()) << "can not prepare " << S_.Quote();
- }
- }
-
- void TSQLiteStatement::Execute() {
- while (Step()) {
- }
-
- Reset();
- }
-
- TSQLiteStatement& TSQLiteStatement::Bind(size_t idx, i64 val) {
- sqlite3_bind_int64(Handle(), idx, val);
- return *this;
- }
-
- TSQLiteStatement& TSQLiteStatement::Bind(size_t idx, int val) {
- sqlite3_bind_int(Handle(), idx, val);
- return *this;
- }
-
- TSQLiteStatement& TSQLiteStatement::Bind(size_t idx) {
- sqlite3_bind_null(Handle(), idx);
- return *this;
- }
-
- TSQLiteStatement& TSQLiteStatement::Bind(size_t idx, double val) {
- sqlite3_bind_double(Handle(), idx, val);
- return *this;
- }
-
- void TSQLiteStatement::BindText(size_t idx, const char* text, size_t len, TFreeFunc func) {
- sqlite3_bind_text(Handle(), idx, text, len, func);
- }
-
- TSQLiteStatement& TSQLiteStatement::Bind(size_t idx, TStringBuf str) {
- BindText(idx, str.data(), str.size(), SQLITE_STATIC);
- return *this;
- }
-
- TSQLiteStatement& TSQLiteStatement::BindBlob(size_t idx, TStringBuf blob) {
- sqlite3_bind_blob(Handle(), idx, blob.data(), blob.size(), SQLITE_STATIC);
- return *this;
- }
-
- size_t TSQLiteStatement::BoundNamePosition(TStringBuf name) const noexcept {
- return sqlite3_bind_parameter_index(Handle(), name.data());
- }
-
- size_t TSQLiteStatement::BoundParameterCount() const noexcept {
- return sqlite3_bind_parameter_count(Handle());
- }
-
- const char* TSQLiteStatement::BoundParameterName(size_t idx) const noexcept {
- return sqlite3_bind_parameter_name(Handle(), idx);
- }
-
- sqlite3_stmt* TSQLiteStatement::Handle() const noexcept {
- return H_.Get();
- }
-
- bool TSQLiteStatement::Step() {
- const int rc = sqlite3_step(Handle());
-
- switch (rc) {
- case SQLITE_ROW:
- return true;
-
- case SQLITE_DONE:
- return false;
-
- default:
- break;
- }
-
- char* stmt = rc == SQLITE_CONSTRAINT ? sqlite3_expanded_sql(Handle()) : nullptr;
- Y_DEFER {
- if (stmt != nullptr) {
- sqlite3_free(reinterpret_cast<void*>(stmt));
- stmt = nullptr;
- }
- };
- if (stmt != nullptr) {
- ythrow TSQLiteError(rc) << "step failed: " << stmt;
- } else {
- ythrow TSQLiteError(rc) << "step failed";
- }
- }
-
- i64 TSQLiteStatement::ColumnInt64(size_t idx) {
- return sqlite3_column_int64(Handle(), idx);
- }
-
- double TSQLiteStatement::ColumnDouble(size_t idx) {
- return sqlite3_column_double(Handle(), idx);
- }
-
- TStringBuf TSQLiteStatement::ColumnText(size_t idx) {
- return reinterpret_cast<const char*>(sqlite3_column_text(Handle(), idx));
- }
-
- TStringBuf TSQLiteStatement::ColumnBlob(size_t idx) {
- const void* blob = sqlite3_column_blob(Handle(), idx);
- size_t size = sqlite3_column_bytes(Handle(), idx);
- return TStringBuf(static_cast<const char*>(blob), size);
- }
-
- void TSQLiteStatement::ColumnAccept(size_t idx, ISQLiteColumnVisitor& visitor) {
- const auto columnType = sqlite3_column_type(Handle(), idx);
- switch (columnType) {
- case SQLITE_INTEGER:
- visitor.OnColumnInt64(ColumnInt64(idx));
- break;
- case SQLITE_FLOAT:
- visitor.OnColumnDouble(ColumnDouble(idx));
- break;
- case SQLITE_TEXT:
- visitor.OnColumnText(ColumnText(idx));
- break;
- case SQLITE_BLOB:
- visitor.OnColumnBlob(ColumnBlob(idx));
- break;
- case SQLITE_NULL:
- visitor.OnColumnNull();
- break;
- }
- }
-
- size_t TSQLiteStatement::ColumnCount() const noexcept {
- return static_cast<size_t>(sqlite3_column_count(Handle()));
- }
-
- TStringBuf TSQLiteStatement::ColumnName(size_t idx) const noexcept {
- return sqlite3_column_name(Handle(), idx);
- }
-
- void TSQLiteStatement::Reset() {
- const int rc = sqlite3_reset(Handle());
-
- if (rc != SQLITE_OK) {
- ythrow TSQLiteError(rc) << "reset failed";
- }
- }
-
- void TSQLiteStatement::ResetHard() {
- (void)sqlite3_reset(Handle());
- }
-
- void TSQLiteStatement::ClearBindings() noexcept {
- // No error is documented.
- // sqlite3.c's code always returns SQLITE_OK.
- (void)sqlite3_clear_bindings(Handle());
- }
-
- TSQLiteTransaction::TSQLiteTransaction(TSQLiteDB& db)
- : Db(&db)
- {
- Execute("BEGIN TRANSACTION");
- }
-
- TSQLiteTransaction::~TSQLiteTransaction() {
- if (Db) {
- Rollback();
- }
- }
-
- void TSQLiteTransaction::Commit() {
- Execute("COMMIT TRANSACTION");
- Db = nullptr;
- }
-
- void TSQLiteTransaction::Rollback() {
- Execute("ROLLBACK TRANSACTION");
- Db = nullptr;
- }
-
- void TSQLiteTransaction::Execute(const TString& query) {
- Y_ENSURE(Db, "Transaction is already ended");
- TSQLiteStatement st(*Db, query);
- st.Execute();
- }
-
- TSimpleDB::TSimpleDB(const TString& path)
- : TSQLiteDB(path)
- , Start_(*this, "begin transaction")
- , End_(*this, "end transaction")
- {
- }
-
- void TSimpleDB::Execute(const TString& statement) {
- TSQLiteStatement(*this, statement).Execute();
- }
-
- void TSimpleDB::Acquire() {
- Start_.Execute();
- }
-
- void TSimpleDB::Release() {
- End_.Execute();
- }
-
-}
diff --git a/library/cpp/sqlite3/sqlite.h b/library/cpp/sqlite3/sqlite.h
deleted file mode 100644
index 8b35e2606a..0000000000
--- a/library/cpp/sqlite3/sqlite.h
+++ /dev/null
@@ -1,136 +0,0 @@
-#pragma once
-
-#include <util/generic/yexception.h>
-#include <util/generic/ptr.h>
-
-#include <contrib/libs/sqlite3/sqlite3.h>
-
-namespace NSQLite {
- class TSQLiteError: public yexception {
- public:
- TSQLiteError(sqlite3* hndl);
- TSQLiteError(int rc);
-
- int GetErrorCode() const {
- return ErrorCode;
- }
-
- private:
- int ErrorCode;
- };
-
- template <class T, int (*Func)(T*)>
- struct TCFree {
- static void Destroy(T* t) {
- Func(t);
- }
- };
-
- class TSQLiteDB {
- public:
- TSQLiteDB(const TString& path, int flags);
- TSQLiteDB(const TString& path);
-
- sqlite3* Handle() const noexcept;
- size_t RowsAffected() const noexcept;
-
- private:
- THolder<sqlite3, TCFree<sqlite3, sqlite3_close>> H_;
- };
-
- class ISQLiteColumnVisitor {
- public:
- virtual ~ISQLiteColumnVisitor() = default;
-
- virtual void OnColumnInt64(i64 value) = 0;
- virtual void OnColumnDouble(double value) = 0;
- virtual void OnColumnText(TStringBuf value) = 0;
- virtual void OnColumnBlob(TStringBuf value) = 0;
- virtual void OnColumnNull() = 0;
- };
-
- class TSQLiteStatement {
- public:
- TSQLiteStatement(TSQLiteDB& db, const TString& s);
-
- void Execute();
- TSQLiteStatement& Bind(size_t idx, i64 val);
- TSQLiteStatement& Bind(size_t idx, int val);
- TSQLiteStatement& Bind(size_t idx);
- TSQLiteStatement& Bind(size_t idx, double val);
- TSQLiteStatement& Bind(size_t idx, TStringBuf str);
- TSQLiteStatement& BindBlob(size_t idx, TStringBuf blob);
- template <typename Value>
- TSQLiteStatement& Bind(TStringBuf name, Value val) {
- size_t idx = BoundNamePosition(name);
- Y_ASSERT(idx > 0);
- return Bind(idx, val);
- }
- TSQLiteStatement& BindBlob(TStringBuf name, TStringBuf blob) {
- size_t idx = BoundNamePosition(name);
- Y_ASSERT(idx > 0);
- return BindBlob(idx, blob);
- }
- TSQLiteStatement& Bind(TStringBuf name) {
- size_t idx = BoundNamePosition(name);
- Y_ASSERT(idx > 0);
- return Bind(idx);
- }
- size_t BoundNamePosition(TStringBuf name) const noexcept;
- size_t BoundParameterCount() const noexcept;
- const char* BoundParameterName(size_t idx) const noexcept;
-
- sqlite3_stmt* Handle() const noexcept;
- bool Step();
- i64 ColumnInt64(size_t idx);
- double ColumnDouble(size_t idx);
- TStringBuf ColumnText(size_t idx);
- TStringBuf ColumnBlob(size_t idx);
- void ColumnAccept(size_t idx, ISQLiteColumnVisitor& visitor);
- size_t ColumnCount() const noexcept;
- TStringBuf ColumnName(size_t idx) const noexcept;
- void Reset();
- // Ignore last error on this statement
- void ResetHard();
- void ClearBindings() noexcept;
-
- private:
- typedef void (*TFreeFunc)(void*);
- void BindText(size_t col, const char* text, size_t len, TFreeFunc func);
-
- private:
- TString S_;
- THolder<sqlite3_stmt, TCFree<sqlite3_stmt, sqlite3_finalize>> H_;
- };
-
- /**
- * Forces user to commit transaction explicitly, to not get exception in destructor (with all consequences of it).
- */
- class TSQLiteTransaction: private TNonCopyable {
- private:
- TSQLiteDB* Db;
-
- public:
- TSQLiteTransaction(TSQLiteDB& db);
- ~TSQLiteTransaction();
-
- void Commit();
- void Rollback();
-
- private:
- void Execute(const TString& query);
- };
-
- class TSimpleDB: public TSQLiteDB {
- public:
- TSimpleDB(const TString& path);
-
- void Execute(const TString& statement);
- void Acquire();
- void Release();
-
- private:
- TSQLiteStatement Start_;
- TSQLiteStatement End_;
- };
-}
diff --git a/library/cpp/sqlite3/ya.make b/library/cpp/sqlite3/ya.make
deleted file mode 100644
index 15417e278d..0000000000
--- a/library/cpp/sqlite3/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-LIBRARY()
-
-SRCS(
- sqlite.cpp
-)
-
-PEERDIR(
- contrib/libs/sqlite3
-)
-
-END()
-
-RECURSE_FOR_TESTS(ut)
diff --git a/library/cpp/streams/growing_file_input/growing_file_input.cpp b/library/cpp/streams/growing_file_input/growing_file_input.cpp
deleted file mode 100644
index 0bbfa5ade9..0000000000
--- a/library/cpp/streams/growing_file_input/growing_file_input.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "growing_file_input.h"
-
-#include <util/datetime/base.h>
-#include <util/generic/yexception.h>
-
-TGrowingFileInput::TGrowingFileInput(const TString& path)
- : File_(path, OpenExisting | RdOnly | Seq)
-{
- if (!File_.IsOpen()) {
- ythrow TIoException() << "file " << path << " not open";
- }
-
- File_.Seek(0, sEnd);
-}
-
-TGrowingFileInput::TGrowingFileInput(const TFile& file)
- : File_(file)
-{
- if (!File_.IsOpen()) {
- ythrow TIoException() << "file (" << file.GetName() << ") not open";
- }
-
- File_.Seek(0, sEnd);
-}
-
-size_t TGrowingFileInput::DoRead(void* buf, size_t len) {
- for (int sleepTime = 1;;) {
- size_t rr = File_.Read(buf, len);
-
- if (rr != 0) {
- return rr;
- }
-
- NanoSleep((ui64)sleepTime * 1000000);
-
- if (sleepTime < 2000) {
- sleepTime <<= 1;
- }
- }
-}
diff --git a/library/cpp/streams/growing_file_input/growing_file_input.h b/library/cpp/streams/growing_file_input/growing_file_input.h
deleted file mode 100644
index 9054a5f3da..0000000000
--- a/library/cpp/streams/growing_file_input/growing_file_input.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include <util/stream/input.h>
-#include <util/system/file.h>
-
-/**
- * Growing file input stream.
- *
- * File descriptor offsets to the end of the file, when the object is created.
- *
- * Read function waites for reading at least one byte.
- */
-class TGrowingFileInput: public IInputStream {
-public:
- TGrowingFileInput(const TFile& file);
- TGrowingFileInput(const TString& path);
-
-private:
- size_t DoRead(void* buf, size_t len) override;
-
-private:
- TFile File_;
-};
diff --git a/library/cpp/streams/growing_file_input/ya.make b/library/cpp/streams/growing_file_input/ya.make
deleted file mode 100644
index 69c56fea46..0000000000
--- a/library/cpp/streams/growing_file_input/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-LIBRARY()
-
-SRCS(
- growing_file_input.cpp
-)
-
-END()
-
-RECURSE_FOR_TESTS(
- ut
-)
diff --git a/library/cpp/string_utils/subst_buf/substbuf.cpp b/library/cpp/string_utils/subst_buf/substbuf.cpp
deleted file mode 100644
index f23cb24b19..0000000000
--- a/library/cpp/string_utils/subst_buf/substbuf.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "substbuf.h"
diff --git a/library/cpp/string_utils/subst_buf/substbuf.h b/library/cpp/string_utils/subst_buf/substbuf.h
deleted file mode 100644
index 357ee68ae3..0000000000
--- a/library/cpp/string_utils/subst_buf/substbuf.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#pragma once
-
-#include <util/generic/vector.h>
-#include <util/generic/strbuf.h>
-#include <util/string/subst.h>
-
-/// Заменяет в строке одни подстроки на другие.
-template <class TBuf, class TPool>
-size_t SubstGlobal(TBuf& s, const TBuf& from, const TBuf& to, TPool& pool) {
- if (from.empty())
- return 0;
-
- TVector<size_t> offs;
- for (size_t off = 0; (off = s.find(from, off)) != TBuf::npos; off += from.length())
- offs.push_back(off);
- if (offs.empty())
- return 0;
-
- size_t dstSize = s.size() + ssize_t(offs.size()) * ssize_t(to.size() - from.size());
- const size_t charTypeSz = sizeof(typename TBuf::char_type);
- typename TBuf::char_type* dst = (typename TBuf::char_type*)pool.Allocate((dstSize + 1) * charTypeSz);
- dst[dstSize] = 0;
-
- typename TBuf::char_type* p = dst;
- size_t lastSrc = 0;
- for (auto off : offs) {
- memcpy(p, s.data() + lastSrc, (off - lastSrc) * charTypeSz);
- p += off - lastSrc;
- lastSrc = off + from.size();
- memcpy(p, to.data(), to.size() * charTypeSz);
- p += to.size();
- }
- memcpy(p, s.data() + lastSrc, (s.size() - lastSrc) * charTypeSz);
- p += s.size() - lastSrc;
- Y_ASSERT(p - dst == (ssize_t)dstSize);
-
- s = TBuf(dst, dstSize);
- return offs.size();
-}
-
-template <class TPool>
-size_t SubstGlobal(TStringBuf& s, const TStringBuf& from, const TStringBuf& to, TPool& pool) {
- return SubstGlobal<TStringBuf, TPool>(s, from, to, pool);
-}
-
-/// Заменяет в строке одни подстроки на другие.
-template <class TBuf, class TPool>
-inline size_t SubstGlobal(TBuf& s, typename TBuf::char_type from, typename TBuf::char_type to, TPool& pool) {
- size_t result = 0;
- size_t off = s.find(from);
- if (off == TBuf::npos)
- return 0;
-
- s = TBuf(pool.Append(s), s.size());
-
- for (typename TBuf::char_type* it = const_cast<typename TBuf::char_type*>(s.begin()) + off; it != s.end(); ++it) {
- if (*it == from) {
- *it = to;
- ++result;
- }
- }
- return result;
-}
diff --git a/library/cpp/string_utils/subst_buf/ya.make b/library/cpp/string_utils/subst_buf/ya.make
deleted file mode 100644
index 8b8793f5b3..0000000000
--- a/library/cpp/string_utils/subst_buf/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-LIBRARY()
-
-SRCS(
- substbuf.cpp
-)
-
-END()
diff --git a/library/cpp/ucompress/README.md b/library/cpp/ucompress/README.md
deleted file mode 100644
index 5a6e9d8f42..0000000000
--- a/library/cpp/ucompress/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Compatible implementation of library/python/compress (also known as "uc" - uber compressor: tools/uc, ya tool uc).
diff --git a/library/cpp/ucompress/common.h b/library/cpp/ucompress/common.h
deleted file mode 100644
index d59cde9cf1..0000000000
--- a/library/cpp/ucompress/common.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-
-namespace NUCompress {
- // These limitations come from original implementation - library/python/compress
- using TBlockLen = ui32;
- constexpr TBlockLen MaxCompressedLen = 100000000;
-}
diff --git a/library/cpp/ucompress/reader.cpp b/library/cpp/ucompress/reader.cpp
deleted file mode 100644
index 45a8ca8da2..0000000000
--- a/library/cpp/ucompress/reader.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#include "reader.h"
-#include "common.h"
-
-#include <library/cpp/blockcodecs/codecs.h>
-#include <library/cpp/json/json_reader.h>
-
-#include <util/system/byteorder.h>
-
-
-using namespace NUCompress;
-
-TDecodedInput::TDecodedInput(IInputStream* in)
- : S_(in)
-{
- Y_ENSURE_EX(S_, TBadArgumentException() << "Null output stream");
-}
-
-TDecodedInput::~TDecodedInput() = default;
-
-size_t TDecodedInput::DoUnboundedNext(const void** ptr) {
- if (!C_) {
- TBlockLen blockLen = 0;
- S_->LoadOrFail(&blockLen, sizeof(blockLen));
- blockLen = LittleToHost(blockLen);
- Y_ENSURE(blockLen <= MaxCompressedLen, "broken stream");
-
- TString buf = TString::Uninitialized(blockLen);
- S_->LoadOrFail(buf.Detach(), blockLen);
-
- NJson::TJsonValue hdr;
- Y_ENSURE(NJson::ReadJsonTree(buf, &hdr), "cannot parse header, suspect old format");
-
- auto& codecName = hdr["codec"].GetString();
- Y_ENSURE(codecName, "header does not have codec info");
-
- // Throws TNotFound
- C_ = NBlockCodecs::Codec(codecName);
- Y_ASSERT(C_);
- }
-
- TBlockLen blockLen = 0;
- size_t actualRead = S_->Load(&blockLen, sizeof(blockLen));
- if (!actualRead) {
- // End of stream
- return 0;
- }
- Y_ENSURE(actualRead == sizeof(blockLen), "broken stream: cannot read block length");
- blockLen = LittleToHost(blockLen);
- Y_ENSURE(blockLen <= MaxCompressedLen, "broken stream");
-
- TBuffer block;
- block.Resize(blockLen);
- S_->LoadOrFail(block.Data(), blockLen);
-
- C_->Decode(block, D_);
- *ptr = D_.Data();
- return D_.Size();
-}
diff --git a/library/cpp/ucompress/reader.h b/library/cpp/ucompress/reader.h
deleted file mode 100644
index 5a5d1c9a89..0000000000
--- a/library/cpp/ucompress/reader.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include <util/generic/buffer.h>
-#include <util/stream/walk.h>
-
-
-namespace NBlockCodecs {
- struct ICodec;
-}
-
-namespace NUCompress {
- class TDecodedInput: public IWalkInput {
- public:
- TDecodedInput(IInputStream* in);
- ~TDecodedInput() override;
-
- private:
- size_t DoUnboundedNext(const void** ptr) override;
-
- private:
- IInputStream* const S_;
- const NBlockCodecs::ICodec* C_ = nullptr;
- TBuffer D_;
- };
-}
diff --git a/library/cpp/ucompress/writer.cpp b/library/cpp/ucompress/writer.cpp
deleted file mode 100644
index 40f8b12108..0000000000
--- a/library/cpp/ucompress/writer.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-#include "writer.h"
-#include "common.h"
-
-#include <library/cpp/blockcodecs/codecs.h>
-#include <library/cpp/json/writer/json.h>
-
-#include <util/generic/scope.h>
-#include <util/generic/yexception.h>
-#include <util/system/byteorder.h>
-
-
-using namespace NUCompress;
-
-TCodedOutput::TCodedOutput(IOutputStream* out, const NBlockCodecs::ICodec* c, size_t bufLen)
- : C_(c)
- , D_(bufLen)
- , S_(out)
-{
- Y_ENSURE_EX(C_, TBadArgumentException() << "Null codec");
- Y_ENSURE_EX(S_, TBadArgumentException() << "Null output stream");
- D_.Resize(bufLen);
- Y_ENSURE_EX(C_->MaxCompressedLength(D_) <= MaxCompressedLen, TBadArgumentException() << "Too big buffer size: " << bufLen);
- D_.Clear();
-}
-
-TCodedOutput::~TCodedOutput() {
- try {
- Finish();
- } catch (...) {
- }
-}
-
-void TCodedOutput::DoWrite(const void* buf, size_t len) {
- Y_ENSURE(S_, "Stream finished already");
- const char* in = static_cast<const char*>(buf);
-
- while (len) {
- const size_t avail = D_.Avail();
- if (len < avail) {
- D_.Append(in, len);
- return;
- }
-
- D_.Append(in, avail);
- Y_ASSERT(!D_.Avail());
- in += avail;
- len -= avail;
-
- FlushImpl();
- }
-}
-
-void TCodedOutput::FlushImpl() {
- if (!HdrWritten) {
- NJsonWriter::TBuf jBuf;
- jBuf.BeginObject();
- jBuf.WriteKey("codec");
- jBuf.WriteString(C_->Name());
- jBuf.EndObject();
-
- TString jStr = jBuf.Str() + '\n';
- const TBlockLen lenToSave = HostToLittle(jStr.length());
- S_->Write(&lenToSave, sizeof(lenToSave));
- S_->Write(jStr.Detach(), jStr.length());
- HdrWritten = true;
- }
-
- O_.Reserve(C_->MaxCompressedLength(D_));
- const size_t oLen = C_->Compress(D_, O_.Data());
- Y_ASSERT(oLen <= MaxCompressedLen);
-
- const TBlockLen lenToSave = HostToLittle(oLen);
- S_->Write(&lenToSave, sizeof(lenToSave));
- S_->Write(O_.Data(), oLen);
-
- D_.Clear();
- O_.Clear();
-}
-
-void TCodedOutput::DoFlush() {
- if (S_ && D_) {
- FlushImpl();
- }
-}
-
-void TCodedOutput::DoFinish() {
- if (S_) {
- Y_DEFER {
- S_ = nullptr;
- };
- FlushImpl();
- // Write zero-length block as EOF marker.
- FlushImpl();
- }
-}
diff --git a/library/cpp/ucompress/writer.h b/library/cpp/ucompress/writer.h
deleted file mode 100644
index 4d3ae71093..0000000000
--- a/library/cpp/ucompress/writer.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include <util/generic/buffer.h>
-#include <util/stream/output.h>
-
-
-namespace NBlockCodecs {
- struct ICodec;
-}
-
-namespace NUCompress {
- class TCodedOutput: public IOutputStream {
- public:
- TCodedOutput(IOutputStream* out, const NBlockCodecs::ICodec* c, size_t bufLen = 16 << 20);
- ~TCodedOutput() override;
-
- private:
- void DoWrite(const void* buf, size_t len) override;
- void DoFlush() override;
- void DoFinish() override;
-
- void FlushImpl();
-
- private:
- const NBlockCodecs::ICodec* const C_;
- TBuffer D_;
- TBuffer O_;
- IOutputStream* S_;
- bool HdrWritten = false;
- };
-}
diff --git a/library/cpp/ucompress/ya.make b/library/cpp/ucompress/ya.make
deleted file mode 100644
index 6582dd9a41..0000000000
--- a/library/cpp/ucompress/ya.make
+++ /dev/null
@@ -1,18 +0,0 @@
-LIBRARY()
-
-PEERDIR(
- library/cpp/blockcodecs
- library/cpp/json
-)
-
-SRCS(
- reader.cpp
- writer.cpp
-)
-
-END()
-
-RECURSE(
- tests
- ut
-)
diff --git a/library/cpp/zipatch/reader.cpp b/library/cpp/zipatch/reader.cpp
deleted file mode 100644
index 03ac365da1..0000000000
--- a/library/cpp/zipatch/reader.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-#include "reader.h"
-
-#include <library/cpp/json/json_reader.h>
-#include <library/cpp/json/json_value.h>
-
-#include <util/generic/hash.h>
-#include <util/memory/tempbuf.h>
-
-#include <contrib/libs/libarchive/libarchive/archive.h>
-#include <contrib/libs/libarchive/libarchive/archive_entry.h>
-
-using namespace NJson;
-
-namespace NZipatch {
-
-class TReader::TImpl {
-
- using TEntry = archive_entry;
-
-public:
- TImpl() {
- if ((Archive_ = archive_read_new()) == nullptr) {
- ythrow yexception() << "can't create archive object";
- }
- }
-
- TImpl(const TFsPath& path)
- : TImpl()
- {
- archive_read_support_filter_all(Archive_);
- archive_read_support_format_zip(Archive_);
-
- if (ARCHIVE_OK != archive_read_open_filename(Archive_, TString(path).c_str(), 10240)) {
- ythrow yexception() << "can't open archive path = " << path;
- }
-
- Read();
- }
-
- TImpl(const TStringBuf buf)
- : TImpl()
- {
- archive_read_support_filter_all(Archive_);
- archive_read_support_format_zip(Archive_);
-
- if (ARCHIVE_OK != archive_read_open_memory(Archive_, buf.data(), buf.size())) {
- ythrow yexception() << "can't open in-memory archive";
- }
-
- Read();
- }
-
- ~TImpl() {
- for (const auto& item : Files_) {
- archive_entry_free(item.second.first);
- }
- if (Archive_) {
- archive_read_free(Archive_);
- }
- }
-
- void Enumerate(TOnEvent cb) const {
- for (const auto& item : Actions_) {
- TEvent event;
-
- event.Action = GetTypeFromString(item["type"].GetStringSafe(TString()));
- event.Path = item["path"].GetStringSafe(TString());
- event.Executable = item["executable"].GetBooleanSafe(false);
- event.Symlink = false;
-
- if (event.Action == Copy || event.Action == Move) {
- event.Source.Path = item["orig_path"].GetStringSafe(TString());
- event.Source.Revision = item["orig_revision"].GetUIntegerRobust();
- }
- if (event.Action == StoreFile) {
- auto fi = Files_.find(event.Path);
- if (fi == Files_.end()) {
- ythrow yexception() << "can't find file; path = " << event.Path;
- }
-
- event.Data = fi->second.second;
- event.Symlink = archive_entry_filetype(fi->second.first) == AE_IFLNK;
- }
-
- if (event.Path) {
- cb(event);
- }
- }
- }
-
-private:
- EAction GetTypeFromString(const TString& type) const {
- if (type == "store_file") {
- return StoreFile;
- }
- if (type == "mkdir") {
- return MkDir;
- }
- if (type == "remove_file" || type == "remove_tree") {
- return Remove;
- }
- if (type == "svn_copy") {
- return Copy;
- }
- return Unknown;
- }
-
- void Read() {
- TEntry* current = nullptr;
-
- while (archive_read_next_header(Archive_, &current) == ARCHIVE_OK) {
- const TStringBuf path(archive_entry_pathname(current));
-
- if (path == "actions.json") {
- TJsonValue value;
- ReadJsonFastTree(GetData(current), &value, true);
-
- for (const auto& item : value.GetArraySafe()) {
- Actions_.push_back(item);
- }
- } else if (AsciiHasPrefix(path, "files/")) {
- TEntry* entry = archive_entry_clone(current);
-
- Files_.emplace(path.substr(6), std::make_pair(entry, GetData(current)));
- }
- }
-
- archive_read_close(Archive_);
- }
-
- TString GetData(TEntry* current) const {
- if (archive_entry_filetype(current) == AE_IFLNK) {
- return archive_entry_symlink(current);
- }
-
- if (const auto size = archive_entry_size(current)) {
- TTempBuf data(size);
-
- if (archive_read_data(Archive_, data.Data(), size) != size) {
- ythrow yexception() << "can't read entry";
- }
-
- return TString(data.Data(), size);
- }
-
- return TString();
- }
-
-private:
- struct archive* Archive_;
- TVector<TJsonValue> Actions_;
- THashMap<TString, std::pair<TEntry*, TString>> Files_;
-};
-
-TReader::TReader(const TFsPath& path)
- : Impl_(new TImpl(path))
-{
-}
-
-TReader::TReader(const TStringBuf buf)
- : Impl_(new TImpl(buf))
-{
-}
-
-TReader::~TReader()
-{ }
-
-void TReader::Enumerate(TOnEvent cb) const {
- Impl_->Enumerate(cb);
-}
-
-} // namespace NZipatch
-
diff --git a/library/cpp/zipatch/reader.h b/library/cpp/zipatch/reader.h
deleted file mode 100644
index a94bc79b71..0000000000
--- a/library/cpp/zipatch/reader.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-
-#include <util/folder/path.h>
-#include <util/generic/ptr.h>
-
-namespace NZipatch {
-
-class TReader {
-public:
- enum EAction {
- Unknown = 0,
- Copy,
- MkDir,
- Move,
- Remove,
- StoreFile,
- };
-
- struct TSource {
- TString Path;
- ui64 Revision;
- };
-
- struct TEvent {
- EAction Action;
- TString Path;
- TStringBuf Data;
- TSource Source;
- bool Executable;
- bool Symlink;
- };
-
- using TOnEvent = std::function<void(const TEvent&)>;
-
-public:
- TReader(const TFsPath& path);
- TReader(const TStringBuf buf);
- ~TReader();
-
- void Enumerate(TOnEvent cb) const;
-
-private:
- class TImpl;
- THolder<TImpl> Impl_;
-};
-
-} // namespace NZipatch
-
diff --git a/library/cpp/zipatch/writer.cpp b/library/cpp/zipatch/writer.cpp
deleted file mode 100644
index a9ca451b01..0000000000
--- a/library/cpp/zipatch/writer.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-#include "writer.h"
-
-#include <library/cpp/json/json_value.h>
-#include <library/cpp/json/json_writer.h>
-
-#include <util/string/join.h>
-
-#include <contrib/libs/libarchive/libarchive/archive.h>
-#include <contrib/libs/libarchive/libarchive/archive_entry.h>
-
-using namespace NJson;
-
-namespace NZipatch {
-
-class TWriter::TImpl {
-public:
- TImpl(const TFsPath& path)
- : Actions_(new TJsonValue(JSON_ARRAY))
- , Meta_(new TJsonValue(JSON_MAP))
- , Revprops_(new TJsonValue(JSON_MAP))
- , Archive_(nullptr)
- {
- Archive_ = archive_write_new();
- if (!Archive_) {
- ythrow yexception() << "can't create archive object";
- }
- archive_write_set_format_zip(Archive_);
- archive_write_zip_set_compression_deflate(Archive_);
-
- if (ARCHIVE_OK != archive_write_open_filename(Archive_, TString(path).c_str())) {
- ythrow yexception() << "can't open archive path = " << path;
- }
- }
-
- ~TImpl() {
- if (Actions_ || Meta_ || Revprops_) {
- Finish();
- }
- if (Archive_) {
- archive_write_free(Archive_);
- }
- }
-
- void Finish() {
- if (Actions_) {
- if (Archive_) {
- WriteEntry("actions.json", WriteJson(Actions_.Get(), true, false));
- }
-
- Actions_.Destroy();
- }
-
- if (Meta_) {
- if (Archive_) {
- WriteEntry("meta.json", WriteJson(Meta_.Get(), true));
- }
-
- Meta_.Destroy();
- }
-
- if (Revprops_) {
- if (Archive_) {
- WriteEntry("revprops.json", WriteJson(Revprops_.Get(), true));
- }
-
- Revprops_.Destroy();
- }
-
- if (Archive_) {
- archive_write_close(Archive_);
- }
- }
-
- void Copy(const TString& path, const TOrigin& origin) {
- Y_ASSERT(origin.Path);
- Y_ASSERT(origin.Revision);
-
- if (Actions_) {
- TJsonValue item;
- item["type"] = "svn_copy";
- item["path"] = path;
- item["orig_path"] = origin.Path;
- item["orig_revision"] = origin.Revision;
- Actions_->AppendValue(item);
- }
- }
-
- void MkDir(const TString& path) {
- if (Actions_) {
- TJsonValue item;
- item["type"] = "mkdir";
- item["path"] = path;
- Actions_->AppendValue(item);
- }
- }
-
- void RemoveFile(const TString& path) {
- if (Actions_) {
- TJsonValue item;
- item["type"] = "remove_file";
- item["path"] = path;
- Actions_->AppendValue(item);
- }
- }
-
- void RemoveTree(const TString& path) {
- if (Actions_) {
- TJsonValue item;
- item["type"] = "remove_tree";
- item["path"] = path;
- Actions_->AppendValue(item);
- }
- }
-
- void StoreFile(
- const TString& path,
- const TString& data,
- const bool execute,
- const bool symlink,
- const TMaybe<bool> binaryHint,
- const TMaybe<bool> encrypted)
- {
- if (Actions_) {
- const TString file = Join("/", "files", path);
- TJsonValue item;
- item["type"] = "store_file";
- item["executable"] = execute;
- item["path"] = path;
- item["file"] = file;
- if (binaryHint.Defined()) {
- item["binary_hint"] = *binaryHint;
- }
- if (encrypted.Defined()) {
- item["encrypted"] = *encrypted;
- }
- Actions_->AppendValue(item);
- WriteEntry(file, data, symlink);
- }
- }
-
- void SetBaseSvnRevision(ui64 revision) {
- if (Meta_) {
- (*Meta_)["base_svn_revision"] = revision;
- }
- }
-
- void AddRevprop(const TString& prop, const TString& value) {
- if (Revprops_) {
- (*Revprops_)[prop] = value;
- }
- }
-
-private:
- void WriteEntry(
- const TString& path,
- const TString& data,
- const bool symlink = false)
- {
- struct archive_entry* const entry = archive_entry_new();
- // Write header.
- archive_entry_set_pathname(entry, path.c_str());
- archive_entry_set_size(entry, data.size());
- archive_entry_set_filetype(entry, symlink ? AE_IFLNK : AE_IFREG);
- archive_entry_set_perm(entry, 0644);
- if (symlink) {
- archive_entry_set_symlink(entry, data.c_str());
- }
- archive_write_header(Archive_, entry);
- // Write data.
- // If entry is symlink then entry size become zero.
- if (archive_entry_size(entry) > 0) {
- archive_write_data(Archive_, data.data(), data.size());
- }
- archive_entry_free(entry);
- }
-
-private:
- THolder<NJson::TJsonValue> Actions_;
- THolder<NJson::TJsonValue> Meta_;
- THolder<NJson::TJsonValue> Revprops_;
- struct archive* Archive_;
-};
-
-TWriter::TWriter(const TFsPath& path)
- : Impl_(new TImpl(path))
-{
-}
-
-TWriter::~TWriter()
-{ }
-
-void TWriter::Finish() {
- Impl_->Finish();
-}
-
-void TWriter::SetBaseSvnRevision(ui64 revision) {
- Impl_->SetBaseSvnRevision(revision);
-}
-
-void TWriter::AddRevprop(const TString& prop, const TString& value) {
- Impl_->AddRevprop(prop, value);
-}
-
-void TWriter::Copy(const TString& path, const TOrigin& origin) {
- Impl_->Copy(path, origin);
-}
-
-void TWriter::MkDir(const TString& path) {
- Impl_->MkDir(path);
-}
-
-void TWriter::RemoveFile(const TString& path) {
- Impl_->RemoveFile(path);
-}
-
-void TWriter::RemoveTree(const TString& path) {
- Impl_->RemoveTree(path);
-}
-
-void TWriter::StoreFile(
- const TString& path,
- const TString& data,
- const bool execute,
- const bool symlink,
- const TMaybe<bool> binaryHint,
- const TMaybe<bool> encrypted)
-{
- Impl_->StoreFile(path, data, execute, symlink, binaryHint, encrypted);
-}
-
-} // namespace NZipatch
-
diff --git a/library/cpp/zipatch/writer.h b/library/cpp/zipatch/writer.h
deleted file mode 100644
index 75cbe49777..0000000000
--- a/library/cpp/zipatch/writer.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#pragma once
-
-#include <util/folder/path.h>
-#include <util/generic/ptr.h>
-#include <util/generic/maybe.h>
-
-namespace NZipatch {
-
-class TWriter {
-public:
- struct TOrigin {
- TString Path;
- ui64 Revision;
-
- inline TOrigin(const TString& path, const ui64 revision)
- : Path(path)
- , Revision(revision)
- { }
- };
-
- TWriter(const TFsPath& path);
- ~TWriter();
-
- void Finish();
-
- void SetBaseSvnRevision(ui64 revision);
-
- void AddRevprop(const TString& prop, const TString& value);
-
- void Copy(const TString& path, const TOrigin& origin);
-
- void MkDir(const TString& path);
-
- void RemoveFile(const TString& path);
-
- void RemoveTree(const TString& path);
-
- void StoreFile(const TString& path,
- const TString& data,
- const bool execute,
- const bool symlink,
- const TMaybe<bool> binaryHint = Nothing(),
- const TMaybe<bool> encrypted = Nothing());
-
-private:
- class TImpl;
- THolder<TImpl> Impl_;
-};
-
-} // namespace NZipatch
-
diff --git a/library/cpp/zipatch/ya.make b/library/cpp/zipatch/ya.make
deleted file mode 100644
index f8fd6006b2..0000000000
--- a/library/cpp/zipatch/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-LIBRARY()
-
-SRCS(
- reader.cpp
- writer.cpp
-)
-
-PEERDIR(
- contrib/libs/libarchive
- library/cpp/json
-)
-
-GENERATE_ENUM_SERIALIZATION(reader.h)
-
-END()
-