opengris-scaler 1.12.7__cp312-cp312-manylinux_2_28_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opengris-scaler might be problematic. Click here for more details.
- opengris_scaler-1.12.7.dist-info/METADATA +729 -0
- opengris_scaler-1.12.7.dist-info/RECORD +232 -0
- opengris_scaler-1.12.7.dist-info/WHEEL +5 -0
- opengris_scaler-1.12.7.dist-info/entry_points.txt +9 -0
- opengris_scaler-1.12.7.dist-info/licenses/LICENSE +201 -0
- opengris_scaler-1.12.7.dist-info/licenses/LICENSE.spdx +7 -0
- opengris_scaler-1.12.7.dist-info/licenses/NOTICE +8 -0
- opengris_scaler.libs/libcapnp-1-b787335c.1.0.so +0 -0
- opengris_scaler.libs/libkj-1-094aa318.1.0.so +0 -0
- scaler/CMakeLists.txt +11 -0
- scaler/__init__.py +14 -0
- scaler/about.py +5 -0
- scaler/client/__init__.py +0 -0
- scaler/client/agent/__init__.py +0 -0
- scaler/client/agent/client_agent.py +210 -0
- scaler/client/agent/disconnect_manager.py +27 -0
- scaler/client/agent/future_manager.py +112 -0
- scaler/client/agent/heartbeat_manager.py +74 -0
- scaler/client/agent/mixins.py +89 -0
- scaler/client/agent/object_manager.py +98 -0
- scaler/client/agent/task_manager.py +64 -0
- scaler/client/client.py +635 -0
- scaler/client/future.py +252 -0
- scaler/client/object_buffer.py +129 -0
- scaler/client/object_reference.py +25 -0
- scaler/client/serializer/__init__.py +0 -0
- scaler/client/serializer/default.py +16 -0
- scaler/client/serializer/mixins.py +38 -0
- scaler/cluster/__init__.py +0 -0
- scaler/cluster/cluster.py +115 -0
- scaler/cluster/combo.py +148 -0
- scaler/cluster/object_storage_server.py +45 -0
- scaler/cluster/scheduler.py +83 -0
- scaler/config/__init__.py +0 -0
- scaler/config/defaults.py +87 -0
- scaler/config/loader.py +95 -0
- scaler/config/mixins.py +15 -0
- scaler/config/section/__init__.py +0 -0
- scaler/config/section/cluster.py +56 -0
- scaler/config/section/native_worker_adapter.py +44 -0
- scaler/config/section/object_storage_server.py +7 -0
- scaler/config/section/scheduler.py +53 -0
- scaler/config/section/symphony_worker_adapter.py +47 -0
- scaler/config/section/top.py +13 -0
- scaler/config/section/webui.py +16 -0
- scaler/config/types/__init__.py +0 -0
- scaler/config/types/object_storage_server.py +45 -0
- scaler/config/types/worker.py +57 -0
- scaler/config/types/zmq.py +79 -0
- scaler/entry_points/__init__.py +0 -0
- scaler/entry_points/cluster.py +133 -0
- scaler/entry_points/object_storage_server.py +41 -0
- scaler/entry_points/scheduler.py +135 -0
- scaler/entry_points/top.py +286 -0
- scaler/entry_points/webui.py +26 -0
- scaler/entry_points/worker_adapter_native.py +137 -0
- scaler/entry_points/worker_adapter_symphony.py +102 -0
- scaler/io/__init__.py +0 -0
- scaler/io/async_binder.py +85 -0
- scaler/io/async_connector.py +95 -0
- scaler/io/async_object_storage_connector.py +185 -0
- scaler/io/mixins.py +154 -0
- scaler/io/sync_connector.py +68 -0
- scaler/io/sync_object_storage_connector.py +185 -0
- scaler/io/sync_subscriber.py +83 -0
- scaler/io/utility.py +31 -0
- scaler/io/ymq/CMakeLists.txt +98 -0
- scaler/io/ymq/__init__.py +0 -0
- scaler/io/ymq/_ymq.pyi +96 -0
- scaler/io/ymq/_ymq.so +0 -0
- scaler/io/ymq/bytes.h +114 -0
- scaler/io/ymq/common.h +29 -0
- scaler/io/ymq/configuration.h +60 -0
- scaler/io/ymq/epoll_context.cpp +185 -0
- scaler/io/ymq/epoll_context.h +85 -0
- scaler/io/ymq/error.h +132 -0
- scaler/io/ymq/event_loop.h +55 -0
- scaler/io/ymq/event_loop_thread.cpp +64 -0
- scaler/io/ymq/event_loop_thread.h +46 -0
- scaler/io/ymq/event_manager.h +81 -0
- scaler/io/ymq/file_descriptor.h +203 -0
- scaler/io/ymq/interruptive_concurrent_queue.h +169 -0
- scaler/io/ymq/io_context.cpp +98 -0
- scaler/io/ymq/io_context.h +44 -0
- scaler/io/ymq/io_socket.cpp +299 -0
- scaler/io/ymq/io_socket.h +121 -0
- scaler/io/ymq/iocp_context.cpp +102 -0
- scaler/io/ymq/iocp_context.h +83 -0
- scaler/io/ymq/logging.h +163 -0
- scaler/io/ymq/message.h +15 -0
- scaler/io/ymq/message_connection.h +16 -0
- scaler/io/ymq/message_connection_tcp.cpp +672 -0
- scaler/io/ymq/message_connection_tcp.h +96 -0
- scaler/io/ymq/network_utils.h +179 -0
- scaler/io/ymq/pymod_ymq/bytes.h +113 -0
- scaler/io/ymq/pymod_ymq/exception.h +124 -0
- scaler/io/ymq/pymod_ymq/gil.h +15 -0
- scaler/io/ymq/pymod_ymq/io_context.h +166 -0
- scaler/io/ymq/pymod_ymq/io_socket.h +285 -0
- scaler/io/ymq/pymod_ymq/message.h +99 -0
- scaler/io/ymq/pymod_ymq/python.h +153 -0
- scaler/io/ymq/pymod_ymq/ymq.cpp +23 -0
- scaler/io/ymq/pymod_ymq/ymq.h +357 -0
- scaler/io/ymq/readme.md +114 -0
- scaler/io/ymq/simple_interface.cpp +80 -0
- scaler/io/ymq/simple_interface.h +24 -0
- scaler/io/ymq/tcp_client.cpp +367 -0
- scaler/io/ymq/tcp_client.h +75 -0
- scaler/io/ymq/tcp_operations.h +41 -0
- scaler/io/ymq/tcp_server.cpp +410 -0
- scaler/io/ymq/tcp_server.h +79 -0
- scaler/io/ymq/third_party/concurrentqueue.h +3747 -0
- scaler/io/ymq/timed_queue.h +272 -0
- scaler/io/ymq/timestamp.h +102 -0
- scaler/io/ymq/typedefs.h +20 -0
- scaler/io/ymq/utils.h +34 -0
- scaler/io/ymq/ymq.py +130 -0
- scaler/object_storage/CMakeLists.txt +50 -0
- scaler/object_storage/__init__.py +0 -0
- scaler/object_storage/constants.h +11 -0
- scaler/object_storage/defs.h +14 -0
- scaler/object_storage/io_helper.cpp +44 -0
- scaler/object_storage/io_helper.h +9 -0
- scaler/object_storage/message.cpp +56 -0
- scaler/object_storage/message.h +130 -0
- scaler/object_storage/object_manager.cpp +126 -0
- scaler/object_storage/object_manager.h +52 -0
- scaler/object_storage/object_storage_server.cpp +359 -0
- scaler/object_storage/object_storage_server.h +126 -0
- scaler/object_storage/object_storage_server.so +0 -0
- scaler/object_storage/pymod_object_storage_server.cpp +104 -0
- scaler/protocol/__init__.py +0 -0
- scaler/protocol/capnp/__init__.py +0 -0
- scaler/protocol/capnp/_python.py +6 -0
- scaler/protocol/capnp/common.capnp +63 -0
- scaler/protocol/capnp/message.capnp +216 -0
- scaler/protocol/capnp/object_storage.capnp +52 -0
- scaler/protocol/capnp/status.capnp +73 -0
- scaler/protocol/introduction.md +105 -0
- scaler/protocol/python/__init__.py +0 -0
- scaler/protocol/python/common.py +135 -0
- scaler/protocol/python/message.py +726 -0
- scaler/protocol/python/mixins.py +13 -0
- scaler/protocol/python/object_storage.py +118 -0
- scaler/protocol/python/status.py +279 -0
- scaler/protocol/worker.md +228 -0
- scaler/scheduler/__init__.py +0 -0
- scaler/scheduler/allocate_policy/__init__.py +0 -0
- scaler/scheduler/allocate_policy/allocate_policy.py +9 -0
- scaler/scheduler/allocate_policy/capability_allocate_policy.py +280 -0
- scaler/scheduler/allocate_policy/even_load_allocate_policy.py +159 -0
- scaler/scheduler/allocate_policy/mixins.py +55 -0
- scaler/scheduler/controllers/__init__.py +0 -0
- scaler/scheduler/controllers/balance_controller.py +65 -0
- scaler/scheduler/controllers/client_controller.py +131 -0
- scaler/scheduler/controllers/config_controller.py +31 -0
- scaler/scheduler/controllers/graph_controller.py +424 -0
- scaler/scheduler/controllers/information_controller.py +81 -0
- scaler/scheduler/controllers/mixins.py +201 -0
- scaler/scheduler/controllers/object_controller.py +147 -0
- scaler/scheduler/controllers/scaling_controller.py +86 -0
- scaler/scheduler/controllers/task_controller.py +373 -0
- scaler/scheduler/controllers/worker_controller.py +168 -0
- scaler/scheduler/object_usage/__init__.py +0 -0
- scaler/scheduler/object_usage/object_tracker.py +131 -0
- scaler/scheduler/scheduler.py +253 -0
- scaler/scheduler/task/__init__.py +0 -0
- scaler/scheduler/task/task_state_machine.py +92 -0
- scaler/scheduler/task/task_state_manager.py +61 -0
- scaler/ui/__init__.py +0 -0
- scaler/ui/constants.py +9 -0
- scaler/ui/live_display.py +118 -0
- scaler/ui/memory_window.py +146 -0
- scaler/ui/setting_page.py +47 -0
- scaler/ui/task_graph.py +370 -0
- scaler/ui/task_log.py +83 -0
- scaler/ui/utility.py +35 -0
- scaler/ui/webui.py +125 -0
- scaler/ui/worker_processors.py +85 -0
- scaler/utility/__init__.py +0 -0
- scaler/utility/debug.py +19 -0
- scaler/utility/event_list.py +63 -0
- scaler/utility/event_loop.py +58 -0
- scaler/utility/exceptions.py +42 -0
- scaler/utility/formatter.py +44 -0
- scaler/utility/graph/__init__.py +0 -0
- scaler/utility/graph/optimization.py +27 -0
- scaler/utility/graph/topological_sorter.py +11 -0
- scaler/utility/graph/topological_sorter_graphblas.py +174 -0
- scaler/utility/identifiers.py +105 -0
- scaler/utility/logging/__init__.py +0 -0
- scaler/utility/logging/decorators.py +25 -0
- scaler/utility/logging/scoped_logger.py +33 -0
- scaler/utility/logging/utility.py +183 -0
- scaler/utility/many_to_many_dict.py +123 -0
- scaler/utility/metadata/__init__.py +0 -0
- scaler/utility/metadata/profile_result.py +31 -0
- scaler/utility/metadata/task_flags.py +30 -0
- scaler/utility/mixins.py +13 -0
- scaler/utility/network_util.py +7 -0
- scaler/utility/one_to_many_dict.py +72 -0
- scaler/utility/queues/__init__.py +0 -0
- scaler/utility/queues/async_indexed_queue.py +37 -0
- scaler/utility/queues/async_priority_queue.py +70 -0
- scaler/utility/queues/async_sorted_priority_queue.py +45 -0
- scaler/utility/queues/indexed_queue.py +114 -0
- scaler/utility/serialization.py +9 -0
- scaler/version.txt +1 -0
- scaler/worker/__init__.py +0 -0
- scaler/worker/agent/__init__.py +0 -0
- scaler/worker/agent/heartbeat_manager.py +107 -0
- scaler/worker/agent/mixins.py +137 -0
- scaler/worker/agent/processor/__init__.py +0 -0
- scaler/worker/agent/processor/object_cache.py +107 -0
- scaler/worker/agent/processor/processor.py +279 -0
- scaler/worker/agent/processor/streaming_buffer.py +28 -0
- scaler/worker/agent/processor_holder.py +145 -0
- scaler/worker/agent/processor_manager.py +365 -0
- scaler/worker/agent/profiling_manager.py +109 -0
- scaler/worker/agent/task_manager.py +150 -0
- scaler/worker/agent/timeout_manager.py +19 -0
- scaler/worker/preload.py +84 -0
- scaler/worker/worker.py +264 -0
- scaler/worker_adapter/__init__.py +0 -0
- scaler/worker_adapter/native.py +154 -0
- scaler/worker_adapter/symphony/__init__.py +0 -0
- scaler/worker_adapter/symphony/callback.py +45 -0
- scaler/worker_adapter/symphony/heartbeat_manager.py +79 -0
- scaler/worker_adapter/symphony/message.py +24 -0
- scaler/worker_adapter/symphony/task_manager.py +288 -0
- scaler/worker_adapter/symphony/worker.py +205 -0
- scaler/worker_adapter/symphony/worker_adapter.py +142 -0
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
#include "scaler/io/ymq/tcp_client.h"
|
|
2
|
+
|
|
3
|
+
#ifdef __linux__
|
|
4
|
+
#include <netinet/in.h>
|
|
5
|
+
#include <sys/socket.h>
|
|
6
|
+
#endif // __linux__
|
|
7
|
+
|
|
8
|
+
#include <cerrno>
|
|
9
|
+
#include <chrono>
|
|
10
|
+
#include <functional>
|
|
11
|
+
#include <memory>
|
|
12
|
+
|
|
13
|
+
#include "scaler/io/ymq/error.h"
|
|
14
|
+
#include "scaler/io/ymq/event_loop_thread.h"
|
|
15
|
+
#include "scaler/io/ymq/event_manager.h"
|
|
16
|
+
#include "scaler/io/ymq/io_socket.h"
|
|
17
|
+
#include "scaler/io/ymq/message_connection_tcp.h"
|
|
18
|
+
#include "scaler/io/ymq/network_utils.h"
|
|
19
|
+
#include "scaler/io/ymq/timestamp.h"
|
|
20
|
+
|
|
21
|
+
namespace scaler {
|
|
22
|
+
namespace ymq {
|
|
23
|
+
|
|
24
|
+
void TcpClient::onCreated()
|
|
25
|
+
{
|
|
26
|
+
assert(_connFd == 0);
|
|
27
|
+
assert(_eventManager.get() != nullptr);
|
|
28
|
+
#ifdef __linux__
|
|
29
|
+
int sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
|
|
30
|
+
|
|
31
|
+
if (sockfd == -1) {
|
|
32
|
+
const int myErrno = errno;
|
|
33
|
+
switch (myErrno) {
|
|
34
|
+
case EACCES:
|
|
35
|
+
case EAFNOSUPPORT:
|
|
36
|
+
case EMFILE:
|
|
37
|
+
case ENFILE:
|
|
38
|
+
case ENOBUFS:
|
|
39
|
+
case ENOMEM:
|
|
40
|
+
unrecoverableError({
|
|
41
|
+
Error::ErrorCode::ConfigurationError,
|
|
42
|
+
"Originated from",
|
|
43
|
+
"socket(2)",
|
|
44
|
+
"Errno is",
|
|
45
|
+
strerror(myErrno),
|
|
46
|
+
});
|
|
47
|
+
break;
|
|
48
|
+
|
|
49
|
+
case EINVAL:
|
|
50
|
+
case EPROTONOSUPPORT:
|
|
51
|
+
default:
|
|
52
|
+
unrecoverableError({
|
|
53
|
+
Error::ErrorCode::CoreBug,
|
|
54
|
+
"Originated from",
|
|
55
|
+
"socket(2)",
|
|
56
|
+
"Errno is",
|
|
57
|
+
strerror(myErrno),
|
|
58
|
+
});
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this->_connFd = sockfd;
|
|
65
|
+
const int ret = connect(sockfd, (sockaddr*)&_remoteAddr, sizeof(_remoteAddr));
|
|
66
|
+
if (ret >= 0) [[unlikely]] {
|
|
67
|
+
std::string id = this->_localIOSocketIdentity;
|
|
68
|
+
auto sock = this->_eventLoopThread->_identityToIOSocket.at(id);
|
|
69
|
+
const bool responsibleForRetry = true;
|
|
70
|
+
sock->onConnectionCreated(setNoDelay(sockfd), getLocalAddr(sockfd), getRemoteAddr(sockfd), responsibleForRetry);
|
|
71
|
+
if (_retryTimes == 0) {
|
|
72
|
+
_onConnectReturn({});
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (errno == EINPROGRESS) {
|
|
78
|
+
_eventLoopThread->_eventLoop.addFdToLoop(sockfd, EPOLLOUT | EPOLLET, this->_eventManager.get());
|
|
79
|
+
if (_retryTimes == 0) {
|
|
80
|
+
_onConnectReturn(std::unexpected {Error::ErrorCode::InitialConnectFailedWithInProgress});
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
CloseAndZeroSocket(sockfd);
|
|
86
|
+
|
|
87
|
+
const int myErrno = errno;
|
|
88
|
+
switch (myErrno) {
|
|
89
|
+
case EACCES:
|
|
90
|
+
case EADDRNOTAVAIL:
|
|
91
|
+
case EFAULT:
|
|
92
|
+
case ENETUNREACH:
|
|
93
|
+
case EPROTOTYPE:
|
|
94
|
+
case ETIMEDOUT:
|
|
95
|
+
unrecoverableError({
|
|
96
|
+
Error::ErrorCode::ConfigurationError,
|
|
97
|
+
"Originated from",
|
|
98
|
+
"connect(2)",
|
|
99
|
+
"Errno is",
|
|
100
|
+
strerror(myErrno),
|
|
101
|
+
"sockfd",
|
|
102
|
+
sockfd,
|
|
103
|
+
});
|
|
104
|
+
break;
|
|
105
|
+
|
|
106
|
+
case EINTR:
|
|
107
|
+
unrecoverableError({
|
|
108
|
+
Error::ErrorCode::SignalNotSupported,
|
|
109
|
+
"Originated from",
|
|
110
|
+
"connect(2)",
|
|
111
|
+
"Errno is",
|
|
112
|
+
strerror(myErrno),
|
|
113
|
+
"sockfd",
|
|
114
|
+
sockfd,
|
|
115
|
+
});
|
|
116
|
+
break;
|
|
117
|
+
|
|
118
|
+
case EPERM:
|
|
119
|
+
case EADDRINUSE:
|
|
120
|
+
case EAFNOSUPPORT:
|
|
121
|
+
case EAGAIN:
|
|
122
|
+
case EALREADY:
|
|
123
|
+
case EBADF:
|
|
124
|
+
case EISCONN:
|
|
125
|
+
case ENOTSOCK:
|
|
126
|
+
unrecoverableError({
|
|
127
|
+
Error::ErrorCode::CoreBug,
|
|
128
|
+
"Originated from",
|
|
129
|
+
"connect(2)",
|
|
130
|
+
"Errno is",
|
|
131
|
+
strerror(myErrno),
|
|
132
|
+
"sockfd",
|
|
133
|
+
sockfd,
|
|
134
|
+
});
|
|
135
|
+
break;
|
|
136
|
+
|
|
137
|
+
case EINPROGRESS:
|
|
138
|
+
case ECONNREFUSED:
|
|
139
|
+
default: break;
|
|
140
|
+
}
|
|
141
|
+
#endif // __linux__
|
|
142
|
+
#ifdef _WIN32
|
|
143
|
+
_connFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
144
|
+
u_long nonblock = 1;
|
|
145
|
+
ioctlsocket(_connFd, FIONBIO, &nonblock);
|
|
146
|
+
DWORD res;
|
|
147
|
+
GUID guid = WSAID_CONNECTEX;
|
|
148
|
+
WSAIoctl(
|
|
149
|
+
this->_connFd,
|
|
150
|
+
SIO_GET_EXTENSION_FUNCTION_POINTER,
|
|
151
|
+
(void*)&guid,
|
|
152
|
+
sizeof(GUID),
|
|
153
|
+
&_connectExFunc,
|
|
154
|
+
sizeof(_connectExFunc),
|
|
155
|
+
&res,
|
|
156
|
+
0,
|
|
157
|
+
0);
|
|
158
|
+
if (!_connectExFunc) {
|
|
159
|
+
unrecoverableError({
|
|
160
|
+
Error::ErrorCode::CoreBug,
|
|
161
|
+
"Originated from",
|
|
162
|
+
"WSAIoctl",
|
|
163
|
+
"Errno is",
|
|
164
|
+
GetErrorCode(),
|
|
165
|
+
"_connFd",
|
|
166
|
+
_connFd,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
_eventLoopThread->_eventLoop.addFdToLoop(_connFd, 0, nullptr);
|
|
170
|
+
|
|
171
|
+
sockaddr_in localAddr = {};
|
|
172
|
+
localAddr.sin_family = AF_INET;
|
|
173
|
+
const char ip4[] = {127, 0, 0, 1};
|
|
174
|
+
*(int*)&localAddr.sin_addr = *(int*)ip4;
|
|
175
|
+
|
|
176
|
+
const int bindRes = bind(_connFd, (struct sockaddr*)&localAddr, sizeof(struct sockaddr_in));
|
|
177
|
+
if (bindRes == -1) {
|
|
178
|
+
unrecoverableError({
|
|
179
|
+
Error::ErrorCode::ConfigurationError,
|
|
180
|
+
"Originated from",
|
|
181
|
+
"bind",
|
|
182
|
+
"Errno is",
|
|
183
|
+
GetErrorCode(),
|
|
184
|
+
"_connFd",
|
|
185
|
+
_connFd,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const bool ok =
|
|
190
|
+
_connectExFunc(_connFd, &_remoteAddr, sizeof(struct sockaddr), NULL, 0, NULL, this->_eventManager.get());
|
|
191
|
+
if (ok) {
|
|
192
|
+
unrecoverableError({
|
|
193
|
+
Error::ErrorCode::CoreBug,
|
|
194
|
+
"Originated from",
|
|
195
|
+
"connectEx",
|
|
196
|
+
"_connFd",
|
|
197
|
+
_connFd,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const int myErrno = GetErrorCode();
|
|
202
|
+
if (myErrno == ERROR_IO_PENDING) {
|
|
203
|
+
if (_retryTimes == 0) {
|
|
204
|
+
_onConnectReturn(std::unexpected {Error::ErrorCode::InitialConnectFailedWithInProgress});
|
|
205
|
+
}
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
unrecoverableError({
|
|
210
|
+
Error::ErrorCode::CoreBug,
|
|
211
|
+
"Originated from",
|
|
212
|
+
"connectEx",
|
|
213
|
+
"Errno is",
|
|
214
|
+
myErrno,
|
|
215
|
+
"_connFd",
|
|
216
|
+
_connFd,
|
|
217
|
+
});
|
|
218
|
+
#endif // _WIN32
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
TcpClient::TcpClient(
|
|
222
|
+
std::shared_ptr<EventLoopThread> eventLoopThread,
|
|
223
|
+
std::string localIOSocketIdentity,
|
|
224
|
+
sockaddr remoteAddr,
|
|
225
|
+
ConnectReturnCallback onConnectReturn,
|
|
226
|
+
size_t maxRetryTimes) noexcept
|
|
227
|
+
: _eventLoopThread(eventLoopThread)
|
|
228
|
+
, _connected(false)
|
|
229
|
+
, _onConnectReturn(std::move(onConnectReturn))
|
|
230
|
+
, _connFd {}
|
|
231
|
+
, _localIOSocketIdentity(std::move(localIOSocketIdentity))
|
|
232
|
+
, _remoteAddr(std::move(remoteAddr))
|
|
233
|
+
, _retryIdentifier {}
|
|
234
|
+
, _eventManager(std::make_unique<EventManager>())
|
|
235
|
+
, _retryTimes {}
|
|
236
|
+
, _maxRetryTimes(maxRetryTimes)
|
|
237
|
+
#ifdef _WIN32
|
|
238
|
+
, _connectExFunc {}
|
|
239
|
+
#endif // _WIN32
|
|
240
|
+
{
|
|
241
|
+
_eventManager->onRead = [this] { this->onRead(); };
|
|
242
|
+
_eventManager->onWrite = [this] { this->onWrite(); };
|
|
243
|
+
_eventManager->onClose = [this] { this->onClose(); };
|
|
244
|
+
_eventManager->onError = [this] { this->onError(); };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
void TcpClient::onRead()
|
|
248
|
+
{
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
void TcpClient::onWrite()
|
|
252
|
+
{
|
|
253
|
+
#ifdef __linux__
|
|
254
|
+
_eventLoopThread->_eventLoop.removeFdFromLoop(_connFd);
|
|
255
|
+
int err {};
|
|
256
|
+
socklen_t errLen {sizeof(err)};
|
|
257
|
+
if (getsockopt(_connFd, SOL_SOCKET, SO_ERROR, &err, &errLen) < 0) {
|
|
258
|
+
const int myErrno = errno;
|
|
259
|
+
switch (myErrno) {
|
|
260
|
+
case ENOPROTOOPT:
|
|
261
|
+
case ENOBUFS:
|
|
262
|
+
case EACCES:
|
|
263
|
+
unrecoverableError({
|
|
264
|
+
Error::ErrorCode::ConfigurationError,
|
|
265
|
+
"Originated from",
|
|
266
|
+
"getsockopt(3)",
|
|
267
|
+
"Errno is",
|
|
268
|
+
strerror(myErrno),
|
|
269
|
+
"_connFd",
|
|
270
|
+
_connFd,
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
case ENOTSOCK:
|
|
274
|
+
case EBADF:
|
|
275
|
+
case EINVAL:
|
|
276
|
+
default:
|
|
277
|
+
unrecoverableError({
|
|
278
|
+
Error::ErrorCode::CoreBug,
|
|
279
|
+
"Originated from",
|
|
280
|
+
"getsockopt(3)",
|
|
281
|
+
"Errno is",
|
|
282
|
+
strerror(myErrno),
|
|
283
|
+
"_connFd",
|
|
284
|
+
_connFd,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (err != 0) {
|
|
290
|
+
if (err == ECONNREFUSED) {
|
|
291
|
+
retry();
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Since connect(2) error has been checked previously
|
|
296
|
+
unrecoverableError({
|
|
297
|
+
Error::ErrorCode::CoreBug,
|
|
298
|
+
"Originated from",
|
|
299
|
+
"connect(2)",
|
|
300
|
+
"Errno is",
|
|
301
|
+
strerror(errno),
|
|
302
|
+
"_connFd",
|
|
303
|
+
_connFd,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
std::string id = this->_localIOSocketIdentity;
|
|
308
|
+
auto sock = this->_eventLoopThread->_identityToIOSocket.at(id);
|
|
309
|
+
const bool responsibleForRetry = true;
|
|
310
|
+
sock->onConnectionCreated(setNoDelay(_connFd), getLocalAddr(_connFd), getRemoteAddr(_connFd), responsibleForRetry);
|
|
311
|
+
|
|
312
|
+
_connFd = 0;
|
|
313
|
+
_connected = true;
|
|
314
|
+
|
|
315
|
+
_eventLoopThread->_eventLoop.executeLater([sock] { sock->removeConnectedTcpClient(); });
|
|
316
|
+
|
|
317
|
+
#endif // __linux__
|
|
318
|
+
#ifdef _WIN32
|
|
319
|
+
const int iResult = setsockopt(_connFd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
|
|
320
|
+
if (iResult == -1) {
|
|
321
|
+
CloseAndZeroSocket(_connFd);
|
|
322
|
+
retry();
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
std::string id = this->_localIOSocketIdentity;
|
|
327
|
+
auto sock = this->_eventLoopThread->_identityToIOSocket.at(id);
|
|
328
|
+
const bool responsibleForRetry = true;
|
|
329
|
+
sock->onConnectionCreated(setNoDelay(_connFd), getLocalAddr(_connFd), getRemoteAddr(_connFd), responsibleForRetry);
|
|
330
|
+
|
|
331
|
+
_connFd = 0;
|
|
332
|
+
_connected = true;
|
|
333
|
+
|
|
334
|
+
_eventLoopThread->_eventLoop.executeLater([sock] { sock->removeConnectedTcpClient(); });
|
|
335
|
+
#endif // _WIN32
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
void TcpClient::retry()
|
|
339
|
+
{
|
|
340
|
+
if (_retryTimes > _maxRetryTimes) {
|
|
341
|
+
_logger.log(Logger::LoggingLevel::error, "Retried times has reached maximum", _maxRetryTimes);
|
|
342
|
+
// exit(1);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
_logger.log(Logger::LoggingLevel::debug, "Client retrying times", _retryTimes);
|
|
347
|
+
CloseAndZeroSocket(_connFd);
|
|
348
|
+
|
|
349
|
+
Timestamp now;
|
|
350
|
+
auto at = now.createTimestampByOffsetDuration(std::chrono::seconds(2 << _retryTimes++));
|
|
351
|
+
|
|
352
|
+
_retryIdentifier = _eventLoopThread->_eventLoop.executeAt(at, [this] { this->onCreated(); });
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
TcpClient::~TcpClient() noexcept
|
|
356
|
+
{
|
|
357
|
+
if (_connFd) {
|
|
358
|
+
_eventLoopThread->_eventLoop.removeFdFromLoop(_connFd);
|
|
359
|
+
CloseAndZeroSocket(_connFd);
|
|
360
|
+
}
|
|
361
|
+
if (_retryTimes > 0) {
|
|
362
|
+
_eventLoopThread->_eventLoop.cancelExecution(_retryIdentifier);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
} // namespace ymq
|
|
367
|
+
} // namespace scaler
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#ifdef __linux__
|
|
4
|
+
#include <sys/socket.h>
|
|
5
|
+
#endif // __linux__
|
|
6
|
+
#ifdef _WIN32
|
|
7
|
+
// clang-format off
|
|
8
|
+
#include <windows.h>
|
|
9
|
+
#include <winsock2.h>
|
|
10
|
+
#include <mswsock.h>
|
|
11
|
+
// clang-format on
|
|
12
|
+
#endif // _WIN32
|
|
13
|
+
|
|
14
|
+
#include <memory>
|
|
15
|
+
|
|
16
|
+
// First-party
|
|
17
|
+
#include "scaler/io/ymq/configuration.h"
|
|
18
|
+
#include "scaler/io/ymq/logging.h"
|
|
19
|
+
|
|
20
|
+
namespace scaler {
|
|
21
|
+
namespace ymq {
|
|
22
|
+
|
|
23
|
+
class EventLoopThread;
|
|
24
|
+
class EventManager;
|
|
25
|
+
|
|
26
|
+
class TcpClient {
|
|
27
|
+
public:
|
|
28
|
+
using ConnectReturnCallback = Configuration::ConnectReturnCallback;
|
|
29
|
+
|
|
30
|
+
TcpClient(
|
|
31
|
+
std::shared_ptr<EventLoopThread> eventLoopThread,
|
|
32
|
+
std::string localIOSocketIdentity,
|
|
33
|
+
sockaddr remoteAddr,
|
|
34
|
+
ConnectReturnCallback onConnectReturn,
|
|
35
|
+
size_t maxRetryTimes) noexcept;
|
|
36
|
+
TcpClient(const TcpClient&) = delete;
|
|
37
|
+
TcpClient& operator=(const TcpClient&) = delete;
|
|
38
|
+
~TcpClient() noexcept;
|
|
39
|
+
|
|
40
|
+
void onCreated();
|
|
41
|
+
void retry();
|
|
42
|
+
|
|
43
|
+
std::shared_ptr<EventLoopThread> _eventLoopThread; /* shared ownership */
|
|
44
|
+
bool _connected;
|
|
45
|
+
|
|
46
|
+
private:
|
|
47
|
+
// Implementation defined method. connect(3) should happen here.
|
|
48
|
+
// This function will call user defined onConnectReturn()
|
|
49
|
+
// It will handle error it can handle. If it is unreasonable to
|
|
50
|
+
// handle the error here, pass it to onConnectReturn()
|
|
51
|
+
void onRead();
|
|
52
|
+
void onWrite();
|
|
53
|
+
void onClose() {}
|
|
54
|
+
void onError() {}
|
|
55
|
+
|
|
56
|
+
ConnectReturnCallback _onConnectReturn;
|
|
57
|
+
int _connFd;
|
|
58
|
+
std::string _localIOSocketIdentity;
|
|
59
|
+
sockaddr _remoteAddr;
|
|
60
|
+
int _retryIdentifier;
|
|
61
|
+
|
|
62
|
+
Logger _logger;
|
|
63
|
+
|
|
64
|
+
std::unique_ptr<EventManager> _eventManager;
|
|
65
|
+
size_t _retryTimes;
|
|
66
|
+
|
|
67
|
+
const size_t _maxRetryTimes;
|
|
68
|
+
|
|
69
|
+
#ifdef _WIN32
|
|
70
|
+
LPFN_CONNECTEX _connectExFunc;
|
|
71
|
+
#endif // _WIN32
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
} // namespace ymq
|
|
75
|
+
} // namespace scaler
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <cstdint> // uint64_t
|
|
4
|
+
|
|
5
|
+
#include "scaler/io/ymq/bytes.h"
|
|
6
|
+
#include "scaler/io/ymq/configuration.h"
|
|
7
|
+
#include "scaler/io/ymq/message.h"
|
|
8
|
+
|
|
9
|
+
namespace scaler {
|
|
10
|
+
namespace ymq {
|
|
11
|
+
|
|
12
|
+
struct TcpReadOperation {
|
|
13
|
+
size_t _cursor {};
|
|
14
|
+
uint64_t _header {};
|
|
15
|
+
Bytes _payload {};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
struct TcpWriteOperation {
|
|
19
|
+
using SendMessageCallback = Configuration::SendMessageCallback;
|
|
20
|
+
uint64_t _header;
|
|
21
|
+
Bytes _address;
|
|
22
|
+
Bytes _payload;
|
|
23
|
+
SendMessageCallback _callbackAfterCompleteWrite;
|
|
24
|
+
|
|
25
|
+
TcpWriteOperation(Message msg, SendMessageCallback callbackAfterCompleteWrite) noexcept
|
|
26
|
+
: _header(msg.payload.len())
|
|
27
|
+
, _payload(std::move(msg.payload))
|
|
28
|
+
, _callbackAfterCompleteWrite(std::move(callbackAfterCompleteWrite))
|
|
29
|
+
{
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
TcpWriteOperation(Bytes payload, SendMessageCallback callbackAfterCompleteWrite) noexcept
|
|
33
|
+
: _header(payload.len())
|
|
34
|
+
, _payload(std::move(payload))
|
|
35
|
+
, _callbackAfterCompleteWrite(std::move(callbackAfterCompleteWrite))
|
|
36
|
+
{
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
} // namespace ymq
|
|
41
|
+
} // namespace scaler
|