opengris-scaler 1.12.7__cp313-cp313-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.

Files changed (232) hide show
  1. opengris_scaler-1.12.7.dist-info/METADATA +729 -0
  2. opengris_scaler-1.12.7.dist-info/RECORD +232 -0
  3. opengris_scaler-1.12.7.dist-info/WHEEL +5 -0
  4. opengris_scaler-1.12.7.dist-info/entry_points.txt +9 -0
  5. opengris_scaler-1.12.7.dist-info/licenses/LICENSE +201 -0
  6. opengris_scaler-1.12.7.dist-info/licenses/LICENSE.spdx +7 -0
  7. opengris_scaler-1.12.7.dist-info/licenses/NOTICE +8 -0
  8. opengris_scaler.libs/libcapnp-1-b787335c.1.0.so +0 -0
  9. opengris_scaler.libs/libkj-1-094aa318.1.0.so +0 -0
  10. scaler/CMakeLists.txt +11 -0
  11. scaler/__init__.py +14 -0
  12. scaler/about.py +5 -0
  13. scaler/client/__init__.py +0 -0
  14. scaler/client/agent/__init__.py +0 -0
  15. scaler/client/agent/client_agent.py +210 -0
  16. scaler/client/agent/disconnect_manager.py +27 -0
  17. scaler/client/agent/future_manager.py +112 -0
  18. scaler/client/agent/heartbeat_manager.py +74 -0
  19. scaler/client/agent/mixins.py +89 -0
  20. scaler/client/agent/object_manager.py +98 -0
  21. scaler/client/agent/task_manager.py +64 -0
  22. scaler/client/client.py +635 -0
  23. scaler/client/future.py +252 -0
  24. scaler/client/object_buffer.py +129 -0
  25. scaler/client/object_reference.py +25 -0
  26. scaler/client/serializer/__init__.py +0 -0
  27. scaler/client/serializer/default.py +16 -0
  28. scaler/client/serializer/mixins.py +38 -0
  29. scaler/cluster/__init__.py +0 -0
  30. scaler/cluster/cluster.py +115 -0
  31. scaler/cluster/combo.py +148 -0
  32. scaler/cluster/object_storage_server.py +45 -0
  33. scaler/cluster/scheduler.py +83 -0
  34. scaler/config/__init__.py +0 -0
  35. scaler/config/defaults.py +87 -0
  36. scaler/config/loader.py +95 -0
  37. scaler/config/mixins.py +15 -0
  38. scaler/config/section/__init__.py +0 -0
  39. scaler/config/section/cluster.py +56 -0
  40. scaler/config/section/native_worker_adapter.py +44 -0
  41. scaler/config/section/object_storage_server.py +7 -0
  42. scaler/config/section/scheduler.py +53 -0
  43. scaler/config/section/symphony_worker_adapter.py +47 -0
  44. scaler/config/section/top.py +13 -0
  45. scaler/config/section/webui.py +16 -0
  46. scaler/config/types/__init__.py +0 -0
  47. scaler/config/types/object_storage_server.py +45 -0
  48. scaler/config/types/worker.py +57 -0
  49. scaler/config/types/zmq.py +79 -0
  50. scaler/entry_points/__init__.py +0 -0
  51. scaler/entry_points/cluster.py +133 -0
  52. scaler/entry_points/object_storage_server.py +41 -0
  53. scaler/entry_points/scheduler.py +135 -0
  54. scaler/entry_points/top.py +286 -0
  55. scaler/entry_points/webui.py +26 -0
  56. scaler/entry_points/worker_adapter_native.py +137 -0
  57. scaler/entry_points/worker_adapter_symphony.py +102 -0
  58. scaler/io/__init__.py +0 -0
  59. scaler/io/async_binder.py +85 -0
  60. scaler/io/async_connector.py +95 -0
  61. scaler/io/async_object_storage_connector.py +185 -0
  62. scaler/io/mixins.py +154 -0
  63. scaler/io/sync_connector.py +68 -0
  64. scaler/io/sync_object_storage_connector.py +185 -0
  65. scaler/io/sync_subscriber.py +83 -0
  66. scaler/io/utility.py +31 -0
  67. scaler/io/ymq/CMakeLists.txt +98 -0
  68. scaler/io/ymq/__init__.py +0 -0
  69. scaler/io/ymq/_ymq.pyi +96 -0
  70. scaler/io/ymq/_ymq.so +0 -0
  71. scaler/io/ymq/bytes.h +114 -0
  72. scaler/io/ymq/common.h +29 -0
  73. scaler/io/ymq/configuration.h +60 -0
  74. scaler/io/ymq/epoll_context.cpp +185 -0
  75. scaler/io/ymq/epoll_context.h +85 -0
  76. scaler/io/ymq/error.h +132 -0
  77. scaler/io/ymq/event_loop.h +55 -0
  78. scaler/io/ymq/event_loop_thread.cpp +64 -0
  79. scaler/io/ymq/event_loop_thread.h +46 -0
  80. scaler/io/ymq/event_manager.h +81 -0
  81. scaler/io/ymq/file_descriptor.h +203 -0
  82. scaler/io/ymq/interruptive_concurrent_queue.h +169 -0
  83. scaler/io/ymq/io_context.cpp +98 -0
  84. scaler/io/ymq/io_context.h +44 -0
  85. scaler/io/ymq/io_socket.cpp +299 -0
  86. scaler/io/ymq/io_socket.h +121 -0
  87. scaler/io/ymq/iocp_context.cpp +102 -0
  88. scaler/io/ymq/iocp_context.h +83 -0
  89. scaler/io/ymq/logging.h +163 -0
  90. scaler/io/ymq/message.h +15 -0
  91. scaler/io/ymq/message_connection.h +16 -0
  92. scaler/io/ymq/message_connection_tcp.cpp +672 -0
  93. scaler/io/ymq/message_connection_tcp.h +96 -0
  94. scaler/io/ymq/network_utils.h +179 -0
  95. scaler/io/ymq/pymod_ymq/bytes.h +113 -0
  96. scaler/io/ymq/pymod_ymq/exception.h +124 -0
  97. scaler/io/ymq/pymod_ymq/gil.h +15 -0
  98. scaler/io/ymq/pymod_ymq/io_context.h +166 -0
  99. scaler/io/ymq/pymod_ymq/io_socket.h +285 -0
  100. scaler/io/ymq/pymod_ymq/message.h +99 -0
  101. scaler/io/ymq/pymod_ymq/python.h +153 -0
  102. scaler/io/ymq/pymod_ymq/ymq.cpp +23 -0
  103. scaler/io/ymq/pymod_ymq/ymq.h +357 -0
  104. scaler/io/ymq/readme.md +114 -0
  105. scaler/io/ymq/simple_interface.cpp +80 -0
  106. scaler/io/ymq/simple_interface.h +24 -0
  107. scaler/io/ymq/tcp_client.cpp +367 -0
  108. scaler/io/ymq/tcp_client.h +75 -0
  109. scaler/io/ymq/tcp_operations.h +41 -0
  110. scaler/io/ymq/tcp_server.cpp +410 -0
  111. scaler/io/ymq/tcp_server.h +79 -0
  112. scaler/io/ymq/third_party/concurrentqueue.h +3747 -0
  113. scaler/io/ymq/timed_queue.h +272 -0
  114. scaler/io/ymq/timestamp.h +102 -0
  115. scaler/io/ymq/typedefs.h +20 -0
  116. scaler/io/ymq/utils.h +34 -0
  117. scaler/io/ymq/ymq.py +130 -0
  118. scaler/object_storage/CMakeLists.txt +50 -0
  119. scaler/object_storage/__init__.py +0 -0
  120. scaler/object_storage/constants.h +11 -0
  121. scaler/object_storage/defs.h +14 -0
  122. scaler/object_storage/io_helper.cpp +44 -0
  123. scaler/object_storage/io_helper.h +9 -0
  124. scaler/object_storage/message.cpp +56 -0
  125. scaler/object_storage/message.h +130 -0
  126. scaler/object_storage/object_manager.cpp +126 -0
  127. scaler/object_storage/object_manager.h +52 -0
  128. scaler/object_storage/object_storage_server.cpp +359 -0
  129. scaler/object_storage/object_storage_server.h +126 -0
  130. scaler/object_storage/object_storage_server.so +0 -0
  131. scaler/object_storage/pymod_object_storage_server.cpp +104 -0
  132. scaler/protocol/__init__.py +0 -0
  133. scaler/protocol/capnp/__init__.py +0 -0
  134. scaler/protocol/capnp/_python.py +6 -0
  135. scaler/protocol/capnp/common.capnp +63 -0
  136. scaler/protocol/capnp/message.capnp +216 -0
  137. scaler/protocol/capnp/object_storage.capnp +52 -0
  138. scaler/protocol/capnp/status.capnp +73 -0
  139. scaler/protocol/introduction.md +105 -0
  140. scaler/protocol/python/__init__.py +0 -0
  141. scaler/protocol/python/common.py +135 -0
  142. scaler/protocol/python/message.py +726 -0
  143. scaler/protocol/python/mixins.py +13 -0
  144. scaler/protocol/python/object_storage.py +118 -0
  145. scaler/protocol/python/status.py +279 -0
  146. scaler/protocol/worker.md +228 -0
  147. scaler/scheduler/__init__.py +0 -0
  148. scaler/scheduler/allocate_policy/__init__.py +0 -0
  149. scaler/scheduler/allocate_policy/allocate_policy.py +9 -0
  150. scaler/scheduler/allocate_policy/capability_allocate_policy.py +280 -0
  151. scaler/scheduler/allocate_policy/even_load_allocate_policy.py +159 -0
  152. scaler/scheduler/allocate_policy/mixins.py +55 -0
  153. scaler/scheduler/controllers/__init__.py +0 -0
  154. scaler/scheduler/controllers/balance_controller.py +65 -0
  155. scaler/scheduler/controllers/client_controller.py +131 -0
  156. scaler/scheduler/controllers/config_controller.py +31 -0
  157. scaler/scheduler/controllers/graph_controller.py +424 -0
  158. scaler/scheduler/controllers/information_controller.py +81 -0
  159. scaler/scheduler/controllers/mixins.py +201 -0
  160. scaler/scheduler/controllers/object_controller.py +147 -0
  161. scaler/scheduler/controllers/scaling_controller.py +86 -0
  162. scaler/scheduler/controllers/task_controller.py +373 -0
  163. scaler/scheduler/controllers/worker_controller.py +168 -0
  164. scaler/scheduler/object_usage/__init__.py +0 -0
  165. scaler/scheduler/object_usage/object_tracker.py +131 -0
  166. scaler/scheduler/scheduler.py +253 -0
  167. scaler/scheduler/task/__init__.py +0 -0
  168. scaler/scheduler/task/task_state_machine.py +92 -0
  169. scaler/scheduler/task/task_state_manager.py +61 -0
  170. scaler/ui/__init__.py +0 -0
  171. scaler/ui/constants.py +9 -0
  172. scaler/ui/live_display.py +118 -0
  173. scaler/ui/memory_window.py +146 -0
  174. scaler/ui/setting_page.py +47 -0
  175. scaler/ui/task_graph.py +370 -0
  176. scaler/ui/task_log.py +83 -0
  177. scaler/ui/utility.py +35 -0
  178. scaler/ui/webui.py +125 -0
  179. scaler/ui/worker_processors.py +85 -0
  180. scaler/utility/__init__.py +0 -0
  181. scaler/utility/debug.py +19 -0
  182. scaler/utility/event_list.py +63 -0
  183. scaler/utility/event_loop.py +58 -0
  184. scaler/utility/exceptions.py +42 -0
  185. scaler/utility/formatter.py +44 -0
  186. scaler/utility/graph/__init__.py +0 -0
  187. scaler/utility/graph/optimization.py +27 -0
  188. scaler/utility/graph/topological_sorter.py +11 -0
  189. scaler/utility/graph/topological_sorter_graphblas.py +174 -0
  190. scaler/utility/identifiers.py +105 -0
  191. scaler/utility/logging/__init__.py +0 -0
  192. scaler/utility/logging/decorators.py +25 -0
  193. scaler/utility/logging/scoped_logger.py +33 -0
  194. scaler/utility/logging/utility.py +183 -0
  195. scaler/utility/many_to_many_dict.py +123 -0
  196. scaler/utility/metadata/__init__.py +0 -0
  197. scaler/utility/metadata/profile_result.py +31 -0
  198. scaler/utility/metadata/task_flags.py +30 -0
  199. scaler/utility/mixins.py +13 -0
  200. scaler/utility/network_util.py +7 -0
  201. scaler/utility/one_to_many_dict.py +72 -0
  202. scaler/utility/queues/__init__.py +0 -0
  203. scaler/utility/queues/async_indexed_queue.py +37 -0
  204. scaler/utility/queues/async_priority_queue.py +70 -0
  205. scaler/utility/queues/async_sorted_priority_queue.py +45 -0
  206. scaler/utility/queues/indexed_queue.py +114 -0
  207. scaler/utility/serialization.py +9 -0
  208. scaler/version.txt +1 -0
  209. scaler/worker/__init__.py +0 -0
  210. scaler/worker/agent/__init__.py +0 -0
  211. scaler/worker/agent/heartbeat_manager.py +107 -0
  212. scaler/worker/agent/mixins.py +137 -0
  213. scaler/worker/agent/processor/__init__.py +0 -0
  214. scaler/worker/agent/processor/object_cache.py +107 -0
  215. scaler/worker/agent/processor/processor.py +279 -0
  216. scaler/worker/agent/processor/streaming_buffer.py +28 -0
  217. scaler/worker/agent/processor_holder.py +145 -0
  218. scaler/worker/agent/processor_manager.py +365 -0
  219. scaler/worker/agent/profiling_manager.py +109 -0
  220. scaler/worker/agent/task_manager.py +150 -0
  221. scaler/worker/agent/timeout_manager.py +19 -0
  222. scaler/worker/preload.py +84 -0
  223. scaler/worker/worker.py +264 -0
  224. scaler/worker_adapter/__init__.py +0 -0
  225. scaler/worker_adapter/native.py +154 -0
  226. scaler/worker_adapter/symphony/__init__.py +0 -0
  227. scaler/worker_adapter/symphony/callback.py +45 -0
  228. scaler/worker_adapter/symphony/heartbeat_manager.py +79 -0
  229. scaler/worker_adapter/symphony/message.py +24 -0
  230. scaler/worker_adapter/symphony/task_manager.py +288 -0
  231. scaler/worker_adapter/symphony/worker.py +205 -0
  232. 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