hikyuu 2.1.0__cp39-none-win_amd64.whl → 2.1.1__cp39-none-win_amd64.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.
- hikyuu/cpp/boost_date_time-mt.dll +0 -0
- hikyuu/cpp/boost_serialization-mt.dll +0 -0
- hikyuu/cpp/boost_wserialization-mt.dll +0 -0
- hikyuu/cpp/core39.pyd +0 -0
- hikyuu/cpp/hikyuu.dll +0 -0
- hikyuu/extend.py +3 -1
- hikyuu/gui/HikyuuTDX.py +11 -6
- hikyuu/include/hikyuu/DataType.h +2 -1
- hikyuu/include/hikyuu/KRecord.h +1 -1
- hikyuu/include/hikyuu/StockManager.h +3 -0
- hikyuu/include/hikyuu/analysis/combinate.h +1 -1
- hikyuu/include/hikyuu/config.h +0 -12
- hikyuu/include/hikyuu/strategy/AccountTradeManager.h +3 -1
- hikyuu/include/hikyuu/utilities/FilterNode.h +267 -0
- hikyuu/include/hikyuu/utilities/LRUCache11.h +230 -0
- hikyuu/include/hikyuu/{Log.h → utilities/Log.h} +91 -113
- hikyuu/include/hikyuu/utilities/Null.h +1 -0
- hikyuu/include/hikyuu/utilities/Parameter.h +2 -1
- hikyuu/include/hikyuu/utilities/ResourcePool.h +636 -0
- hikyuu/include/hikyuu/utilities/SpendTimer.h +10 -9
- hikyuu/include/hikyuu/utilities/TimerManager.h +2 -2
- hikyuu/include/hikyuu/utilities/any_to_string.h +142 -0
- hikyuu/include/hikyuu/utilities/arithmetic.h +69 -33
- hikyuu/include/hikyuu/utilities/base64.h +59 -0
- hikyuu/include/hikyuu/utilities/config.h +41 -0
- hikyuu/include/hikyuu/utilities/datetime/Datetime.h +41 -31
- hikyuu/include/hikyuu/utilities/datetime/TimeDelta.h +24 -13
- hikyuu/include/hikyuu/utilities/db_connect/DBCondition.h +48 -48
- hikyuu/include/hikyuu/utilities/db_connect/DBConnect.h +10 -0
- hikyuu/include/hikyuu/utilities/db_connect/DBConnectBase.h +5 -22
- hikyuu/include/hikyuu/utilities/db_connect/DBUpgrade.h +3 -3
- hikyuu/include/hikyuu/utilities/db_connect/SQLException.h +1 -1
- hikyuu/include/hikyuu/utilities/db_connect/SQLResultSet.h +1 -1
- hikyuu/include/hikyuu/utilities/db_connect/SQLStatementBase.h +7 -7
- hikyuu/include/hikyuu/utilities/db_connect/TableMacro.h +1 -2
- hikyuu/include/hikyuu/utilities/db_connect/mysql/MySQLConnect.h +9 -9
- hikyuu/include/hikyuu/utilities/db_connect/mysql/MySQLStatement.h +18 -18
- hikyuu/include/hikyuu/utilities/db_connect/sqlite/SQLiteConnect.h +3 -3
- hikyuu/include/hikyuu/utilities/db_connect/sqlite/SQLiteStatement.h +2 -2
- hikyuu/include/hikyuu/utilities/db_connect/sqlite/SQLiteUtil.h +6 -6
- hikyuu/include/hikyuu/{exception.h → utilities/exception.h} +1 -0
- hikyuu/include/hikyuu/utilities/http_client/HttpClient.h +229 -0
- hikyuu/include/hikyuu/utilities/http_client/nng_wrap.h +517 -0
- hikyuu/include/hikyuu/utilities/http_client/url.h +25 -0
- hikyuu/include/hikyuu/utilities/{IniParser.h → ini_parser/IniParser.h} +10 -5
- hikyuu/include/hikyuu/utilities/ini_parser/__init__.py +1 -0
- hikyuu/include/hikyuu/utilities/md5.h +41 -0
- hikyuu/include/hikyuu/utilities/mo/__init__.py +1 -0
- hikyuu/include/hikyuu/utilities/mo/mo.h +48 -0
- hikyuu/include/hikyuu/utilities/mo/moFileReader.h +836 -0
- hikyuu/include/hikyuu/{global → utilities}/node/NodeClient.h +25 -18
- hikyuu/include/hikyuu/{global → utilities}/node/NodeError.h +1 -1
- hikyuu/include/hikyuu/{global → utilities}/node/NodeMessage.h +3 -2
- hikyuu/include/hikyuu/utilities/node/NodeServer.h +246 -0
- hikyuu/include/hikyuu/utilities/node/__init__.py +1 -0
- hikyuu/include/hikyuu/utilities/os.h +16 -15
- hikyuu/include/hikyuu/utilities/snowflake.h +110 -0
- hikyuu/include/hikyuu/utilities/string_view.h +70 -0
- hikyuu/include/hikyuu/utilities/thread/MQStealThreadPool.h +3 -3
- hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +3 -3
- hikyuu/include/hikyuu/utilities/thread/StealThreadPool.h +3 -3
- hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +3 -3
- hikyuu/include/hikyuu/version.h +4 -4
- hikyuu/sqlite3.dll +0 -0
- hikyuu/vcruntime140.dll +0 -0
- hikyuu/vcruntime140_1.dll +0 -0
- hikyuu-2.1.1.dist-info/METADATA +115 -0
- {hikyuu-2.1.0.dist-info → hikyuu-2.1.1.dist-info}/RECORD +73 -53
- {hikyuu-2.1.0.dist-info → hikyuu-2.1.1.dist-info}/top_level.txt +4 -1
- hikyuu/README.rst +0 -79
- hikyuu-2.1.0.dist-info/METADATA +0 -126
- /hikyuu/include/hikyuu/{global/node → utilities/http_client}/__init__.py +0 -0
- {hikyuu-2.1.0.dist-info → hikyuu-2.1.1.dist-info}/LICENSE +0 -0
- {hikyuu-2.1.0.dist-info → hikyuu-2.1.1.dist-info}/WHEEL +0 -0
- {hikyuu-2.1.0.dist-info → hikyuu-2.1.1.dist-info}/entry_points.txt +0 -0
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
|
+
#include "hikyuu/utilities/config.h"
|
|
11
|
+
#if !HKU_ENABLE_NODE
|
|
12
|
+
#error "Don't enable node client, please config with --node=y"
|
|
13
|
+
#endif
|
|
14
|
+
|
|
10
15
|
#include <atomic>
|
|
11
16
|
#include <nng/nng.h>
|
|
12
17
|
#include <nng/protocol/reqrep0/req.h>
|
|
@@ -59,13 +64,11 @@ public:
|
|
|
59
64
|
|
|
60
65
|
return true;
|
|
61
66
|
|
|
67
|
+
} catch (const std::exception& e) {
|
|
68
|
+
HKU_ERROR_IF(m_show_log, "Failed dail server: {}! {}", m_server_addr, e.what());
|
|
62
69
|
} catch (...) {
|
|
70
|
+
HKU_ERROR_IF(m_show_log, "Failed dail server: {}! Unknown error!", m_server_addr);
|
|
63
71
|
}
|
|
64
|
-
// } catch (const std::exception& e) {
|
|
65
|
-
// HKU_ERROR("Failed dail server: {}! {}", m_server_addr, e.what());
|
|
66
|
-
// } catch (...) {
|
|
67
|
-
// HKU_ERROR("Failed dail server: {}! Unknown error!", m_server_addr);
|
|
68
|
-
// }
|
|
69
72
|
|
|
70
73
|
m_connected = false;
|
|
71
74
|
nng_close(m_socket);
|
|
@@ -101,6 +104,10 @@ public:
|
|
|
101
104
|
return _send(req) && _recv(res);
|
|
102
105
|
}
|
|
103
106
|
|
|
107
|
+
void showLog(bool show) {
|
|
108
|
+
m_show_log = show;
|
|
109
|
+
}
|
|
110
|
+
|
|
104
111
|
private:
|
|
105
112
|
bool _send(const json& req) const noexcept {
|
|
106
113
|
bool success = false;
|
|
@@ -118,13 +125,11 @@ private:
|
|
|
118
125
|
NODE_NNG_CHECK(rv, "Failed nng_sendmsg!");
|
|
119
126
|
success = true;
|
|
120
127
|
|
|
128
|
+
} catch (const std::exception& e) {
|
|
129
|
+
HKU_ERROR_IF(m_show_log, "Failed send result! {}", e.what());
|
|
121
130
|
} catch (...) {
|
|
131
|
+
HKU_ERROR_IF(m_show_log, "Failed send result! Unknown error!");
|
|
122
132
|
}
|
|
123
|
-
// } catch (const std::exception& e) {
|
|
124
|
-
// HKU_ERROR("Failed send result! {}", e.what());
|
|
125
|
-
// } catch (...) {
|
|
126
|
-
// HKU_ERROR("Failed send result! Unknown error!");
|
|
127
|
-
// }
|
|
128
133
|
|
|
129
134
|
if (!success) {
|
|
130
135
|
nng_msg_free(msg);
|
|
@@ -137,21 +142,22 @@ private:
|
|
|
137
142
|
bool success = false;
|
|
138
143
|
nng_msg* msg{nullptr};
|
|
139
144
|
int rv = nng_recvmsg(m_socket, &msg, 0);
|
|
140
|
-
|
|
141
|
-
|
|
145
|
+
if (rv != 0) {
|
|
146
|
+
HKU_ERROR_IF(m_show_log, "Failed nng_recvmsg! {}", nng_strerror(rv));
|
|
147
|
+
return success;
|
|
148
|
+
}
|
|
149
|
+
|
|
142
150
|
m_last_ack_time = Datetime::now();
|
|
143
151
|
|
|
144
152
|
try {
|
|
145
153
|
res = decodeMsg(msg);
|
|
146
154
|
success = true;
|
|
147
155
|
|
|
156
|
+
} catch (const std::exception& e) {
|
|
157
|
+
HKU_ERROR_IF(m_show_log, "Failed recv response! {}", e.what());
|
|
148
158
|
} catch (...) {
|
|
159
|
+
HKU_ERROR_IF(m_show_log, "Failed recv response! Unknown error!");
|
|
149
160
|
}
|
|
150
|
-
// } catch (const std::exception& e) {
|
|
151
|
-
// HKU_ERROR("Failed recv response! {}", e.what());
|
|
152
|
-
// } catch (...) {
|
|
153
|
-
// HKU_ERROR("Failed recv response! Unknown error!");
|
|
154
|
-
// }
|
|
155
161
|
|
|
156
162
|
nng_msg_free(msg);
|
|
157
163
|
return success;
|
|
@@ -161,8 +167,9 @@ private:
|
|
|
161
167
|
std::mutex m_mutex;
|
|
162
168
|
std::string m_server_addr; // 服务端地址
|
|
163
169
|
nng_socket m_socket;
|
|
164
|
-
std::atomic_bool m_connected{false};
|
|
165
170
|
Datetime m_last_ack_time{Datetime::now()}; // 最后一次接收服务端响应的时间
|
|
171
|
+
std::atomic_bool m_connected{false};
|
|
172
|
+
std::atomic_bool m_show_log{true};
|
|
166
173
|
};
|
|
167
174
|
|
|
168
175
|
} // namespace hku
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#include <vector>
|
|
13
13
|
#include <nng/nng.h>
|
|
14
14
|
#include <nlohmann/json.hpp>
|
|
15
|
+
#include <hikyuu/utilities/Log.h>
|
|
15
16
|
#include "NodeError.h"
|
|
16
17
|
|
|
17
18
|
using json = nlohmann::json;
|
|
@@ -26,8 +27,8 @@ namespace hku {
|
|
|
26
27
|
* req ->
|
|
27
28
|
* {"cmd": int, ...}
|
|
28
29
|
*
|
|
29
|
-
*
|
|
30
|
-
* {"
|
|
30
|
+
* <- res
|
|
31
|
+
* {"ret": code, "msg": str} // msg 存在错误时返回错误信息 (可选)
|
|
31
32
|
*
|
|
32
33
|
*
|
|
33
34
|
*/
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2022 hikyuu.org
|
|
3
|
+
*
|
|
4
|
+
* Created on: 2022-04-15
|
|
5
|
+
* Author: fasiondog
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include "hikyuu/utilities/config.h"
|
|
11
|
+
#if !HKU_ENABLE_NODE
|
|
12
|
+
#error "Don't enable node server, please config with --node=y"
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
#include <string>
|
|
16
|
+
#include <unordered_map>
|
|
17
|
+
#include <nng/nng.h>
|
|
18
|
+
#include <nng/protocol/reqrep0/rep.h>
|
|
19
|
+
|
|
20
|
+
#include <hikyuu/utilities/osdef.h>
|
|
21
|
+
#if HKU_OS_WINDOWS
|
|
22
|
+
#ifndef NOMINMAX
|
|
23
|
+
#define NOMINMAX
|
|
24
|
+
#endif
|
|
25
|
+
#include <WS2tcpip.h>
|
|
26
|
+
#include <Ws2ipdef.h>
|
|
27
|
+
#else
|
|
28
|
+
#include <arpa/inet.h>
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
#include "hikyuu/utilities/Log.h"
|
|
32
|
+
#include "NodeMessage.h"
|
|
33
|
+
|
|
34
|
+
namespace hku {
|
|
35
|
+
|
|
36
|
+
class NodeServer {
|
|
37
|
+
CLASS_LOGGER_IMP(NodeServer)
|
|
38
|
+
|
|
39
|
+
public:
|
|
40
|
+
NodeServer() = default;
|
|
41
|
+
explicit NodeServer(const std::string& addr) : m_addr(addr) {}
|
|
42
|
+
virtual ~NodeServer() {
|
|
43
|
+
stop();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
void setAddr(const std::string& addr) {
|
|
47
|
+
m_addr = addr;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
void regHandle(const std::string& cmd, const std::function<json(json&& req)>& handle) {
|
|
51
|
+
m_handles[cmd] = handle;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void regHandle(const std::string& cmd, std::function<json(json&& req)>&& handle) {
|
|
55
|
+
m_handles[cmd] = std::move(handle);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
void start(size_t max_parrel = 128) {
|
|
59
|
+
CLS_CHECK(!m_addr.empty(), "You must set NodeServer's addr first!");
|
|
60
|
+
|
|
61
|
+
// 启动 node server
|
|
62
|
+
int rv = nng_rep0_open(&m_socket);
|
|
63
|
+
CLS_CHECK(0 == rv, "Failed open server socket! {}", nng_strerror(rv));
|
|
64
|
+
rv = nng_listen(m_socket, m_addr.c_str(), &m_listener, 0);
|
|
65
|
+
CLS_CHECK(0 == rv, "Failed listen node server socket ({})! {}", m_addr, nng_strerror(rv));
|
|
66
|
+
CLS_TRACE("channel lisenter server: {}", m_addr);
|
|
67
|
+
|
|
68
|
+
m_works.resize(max_parrel);
|
|
69
|
+
for (size_t i = 0, total = m_works.size(); i < total; i++) {
|
|
70
|
+
Work* w = &m_works[i];
|
|
71
|
+
rv = nng_aio_alloc(&w->aio, _serverCallback, w);
|
|
72
|
+
CLS_CHECK(0 == rv, "Failed create work {}! {}", i, nng_strerror(rv));
|
|
73
|
+
rv = nng_ctx_open(&w->ctx, m_socket);
|
|
74
|
+
CLS_CHECK(0 == rv, "Failed open ctx {}! {}", i, nng_strerror(rv));
|
|
75
|
+
w->state = Work::INIT;
|
|
76
|
+
w->server = this;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (size_t i = 0, total = m_works.size(); i < total; i++) {
|
|
80
|
+
_serverCallback(&m_works[i]);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
void loop() {
|
|
85
|
+
while (true) {
|
|
86
|
+
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
void stop() {
|
|
91
|
+
HKU_IF_RETURN(m_works.empty(), void());
|
|
92
|
+
for (size_t i = 0, total = m_works.size(); i < total; i++) {
|
|
93
|
+
Work* w = &m_works[i];
|
|
94
|
+
w->server = nullptr;
|
|
95
|
+
w->state = Work::FINISH;
|
|
96
|
+
if (w->aio) {
|
|
97
|
+
nng_aio_stop(w->aio);
|
|
98
|
+
nng_aio_free(w->aio);
|
|
99
|
+
nng_ctx_close(w->ctx);
|
|
100
|
+
w->aio = nullptr;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 关闭 socket 服务节点
|
|
105
|
+
nng_listener_close(m_listener);
|
|
106
|
+
nng_close(m_socket);
|
|
107
|
+
m_works.clear();
|
|
108
|
+
CLS_INFO("stopped node server.");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private:
|
|
112
|
+
struct Work {
|
|
113
|
+
enum { INIT, RECV, SEND, FINISH } state = INIT;
|
|
114
|
+
nng_aio* aio{nullptr};
|
|
115
|
+
nng_ctx ctx;
|
|
116
|
+
NodeServer* server{nullptr};
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
static void _serverCallback(void* arg) {
|
|
120
|
+
Work* work = static_cast<Work*>(arg);
|
|
121
|
+
int rv = 0;
|
|
122
|
+
switch (work->state) {
|
|
123
|
+
case Work::INIT:
|
|
124
|
+
work->state = Work::RECV;
|
|
125
|
+
nng_ctx_recv(work->ctx, work->aio);
|
|
126
|
+
break;
|
|
127
|
+
|
|
128
|
+
case Work::RECV:
|
|
129
|
+
_processRequest(work);
|
|
130
|
+
break;
|
|
131
|
+
|
|
132
|
+
case Work::SEND:
|
|
133
|
+
if ((rv = nng_aio_result(work->aio)) != 0) {
|
|
134
|
+
CLS_FATAL("Failed nng_ctx_send! {}", nng_strerror(rv));
|
|
135
|
+
work->state = Work::FINISH;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
work->state = Work::RECV;
|
|
139
|
+
nng_ctx_recv(work->ctx, work->aio);
|
|
140
|
+
break;
|
|
141
|
+
|
|
142
|
+
case Work::FINISH:
|
|
143
|
+
break;
|
|
144
|
+
|
|
145
|
+
default:
|
|
146
|
+
CLS_FATAL("nng bad state!");
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static void _processRequest(Work* work) {
|
|
152
|
+
NodeServer* server = work->server;
|
|
153
|
+
CLS_IF_RETURN(!server || !work->aio, void());
|
|
154
|
+
nng_msg* msg = nullptr;
|
|
155
|
+
json res;
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
int rv = nng_aio_result(work->aio);
|
|
159
|
+
HKU_CHECK(rv == 0, "Failed nng_aio_result!");
|
|
160
|
+
|
|
161
|
+
msg = nng_aio_get_msg(work->aio);
|
|
162
|
+
json req = decodeMsg(msg);
|
|
163
|
+
NODE_CHECK(req.contains("cmd"), NodeErrorCode::MISSING_CMD, "Missing command!");
|
|
164
|
+
|
|
165
|
+
// 兼容老版本数字cmd
|
|
166
|
+
std::string cmd = req["cmd"].is_number() ? fmt::format("{}", req["cmd"].get<int>())
|
|
167
|
+
: req["cmd"].get<std::string>();
|
|
168
|
+
auto iter = server->m_handles.find(cmd);
|
|
169
|
+
NODE_CHECK(iter != server->m_handles.end(), NodeErrorCode::INVALID_CMD,
|
|
170
|
+
"The server does not know how to process the message: {}", cmd);
|
|
171
|
+
|
|
172
|
+
// tcp 连接尝试获取客户端地址和端口加入 req 中
|
|
173
|
+
req["remote_host"] = "";
|
|
174
|
+
req["remote_port"] = 0;
|
|
175
|
+
nng_pipe p = nng_msg_get_pipe(msg);
|
|
176
|
+
if (nng_pipe_id(p) > 0) {
|
|
177
|
+
uint16_t port = 0;
|
|
178
|
+
nng_sockaddr ra;
|
|
179
|
+
rv = nng_pipe_get_addr(p, NNG_OPT_REMADDR, &ra);
|
|
180
|
+
if (rv == 0) {
|
|
181
|
+
if (ra.s_family == NNG_AF_INET) {
|
|
182
|
+
char ipAddr[INET_ADDRSTRLEN];
|
|
183
|
+
inet_ntop(AF_INET, (void*)&ra.s_in.sa_addr, ipAddr, INET_ADDRSTRLEN);
|
|
184
|
+
port = ntohs(ra.s_in.sa_port);
|
|
185
|
+
req["remote_host"] = ipAddr;
|
|
186
|
+
req["remote_port"] = port;
|
|
187
|
+
} else if (ra.s_family == NNG_AF_INET6) {
|
|
188
|
+
char ipAddr[INET6_ADDRSTRLEN];
|
|
189
|
+
inet_ntop(AF_INET6, (void*)&ra.s_in.sa_addr, ipAddr, INET6_ADDRSTRLEN);
|
|
190
|
+
port = ntohs(ra.s_in6.sa_port);
|
|
191
|
+
req["remote_host"] = ipAddr;
|
|
192
|
+
req["remote_port"] = port;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
res = iter->second(std::move(req));
|
|
198
|
+
res["ret"] = NodeErrorCode::SUCCESS;
|
|
199
|
+
encodeMsg(msg, res);
|
|
200
|
+
|
|
201
|
+
nng_aio_set_msg(work->aio, msg);
|
|
202
|
+
work->state = Work::SEND;
|
|
203
|
+
nng_ctx_send(work->ctx, work->aio);
|
|
204
|
+
|
|
205
|
+
} catch (const NodeNngError& e) {
|
|
206
|
+
CLS_FATAL(e.what());
|
|
207
|
+
work->state = Work::FINISH;
|
|
208
|
+
|
|
209
|
+
} catch (const NodeError& e) {
|
|
210
|
+
CLS_ERROR(e.what());
|
|
211
|
+
res["ret"] = e.errcode();
|
|
212
|
+
res["msg"] = e.what();
|
|
213
|
+
encodeMsg(msg, res);
|
|
214
|
+
nng_aio_set_msg(work->aio, msg);
|
|
215
|
+
work->state = Work::SEND;
|
|
216
|
+
nng_ctx_send(work->ctx, work->aio);
|
|
217
|
+
|
|
218
|
+
} catch (const std::exception& e) {
|
|
219
|
+
CLS_ERROR(e.what());
|
|
220
|
+
res["ret"] = NodeErrorCode::UNKNOWN_ERROR;
|
|
221
|
+
res["msg"] = e.what();
|
|
222
|
+
encodeMsg(msg, res);
|
|
223
|
+
nng_aio_set_msg(work->aio, msg);
|
|
224
|
+
work->state = Work::SEND;
|
|
225
|
+
nng_ctx_send(work->ctx, work->aio);
|
|
226
|
+
|
|
227
|
+
} catch (...) {
|
|
228
|
+
std::string errmsg = "Unknown error!";
|
|
229
|
+
CLS_ERROR(errmsg);
|
|
230
|
+
res["ret"] = NodeErrorCode::UNKNOWN_ERROR;
|
|
231
|
+
res["msg"] = errmsg;
|
|
232
|
+
nng_aio_set_msg(work->aio, msg);
|
|
233
|
+
work->state = Work::SEND;
|
|
234
|
+
nng_ctx_send(work->ctx, work->aio);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
private:
|
|
239
|
+
std::string m_addr;
|
|
240
|
+
nng_socket m_socket;
|
|
241
|
+
nng_listener m_listener;
|
|
242
|
+
std::vector<Work> m_works;
|
|
243
|
+
std::unordered_map<std::string, std::function<json(json&& req)>> m_handles;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
} // namespace hku
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
#include "arithmetic.h"
|
|
18
18
|
#include <cstdint>
|
|
19
19
|
|
|
20
|
-
#ifndef
|
|
21
|
-
#define
|
|
20
|
+
#ifndef HKU_UTILS_API
|
|
21
|
+
#define HKU_UTILS_API
|
|
22
22
|
#endif
|
|
23
23
|
|
|
24
24
|
namespace hku {
|
|
@@ -27,27 +27,27 @@ namespace hku {
|
|
|
27
27
|
* 判断文件或目录是否存在
|
|
28
28
|
* @param filename 文件名或目录名
|
|
29
29
|
*/
|
|
30
|
-
bool
|
|
30
|
+
bool HKU_UTILS_API existFile(const std::string &filename) noexcept;
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* 创建目录
|
|
34
34
|
* @param pathname 路径名
|
|
35
35
|
* @return 如果目录已存在或者创建成功返回 true,否则返回 false
|
|
36
36
|
*/
|
|
37
|
-
bool
|
|
37
|
+
bool HKU_UTILS_API createDir(const std::string &pathname) noexcept;
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* 删除文件
|
|
41
41
|
* @param filename 文件名
|
|
42
42
|
* @return 删除失败或文件不存在时返回false
|
|
43
43
|
*/
|
|
44
|
-
bool
|
|
44
|
+
bool HKU_UTILS_API removeFile(const std::string &filename) noexcept;
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* 删除目录及其包含的文件和子目录
|
|
48
48
|
* @param path 待删除目录
|
|
49
49
|
*/
|
|
50
|
-
bool
|
|
50
|
+
bool HKU_UTILS_API removeDir(const std::string &path) noexcept;
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
* 拷贝文件
|
|
@@ -55,7 +55,8 @@ bool HKU_API removeDir(const std::string& path) noexcept;
|
|
|
55
55
|
* @param dst 目标文件
|
|
56
56
|
* @param flush 是否立即落盘
|
|
57
57
|
*/
|
|
58
|
-
bool
|
|
58
|
+
bool HKU_UTILS_API copyFile(const std::string &src, const std::string &dst,
|
|
59
|
+
bool flush = false) noexcept;
|
|
59
60
|
|
|
60
61
|
/**
|
|
61
62
|
* 文件、目录改名或移动
|
|
@@ -65,23 +66,23 @@ bool HKU_API copyFile(const std::string& src, const std::string& dst, bool flush
|
|
|
65
66
|
* @return true 成功
|
|
66
67
|
* @return false 失败 旧名文件不存在,或文件被占用等其他原因导致的失败
|
|
67
68
|
*/
|
|
68
|
-
bool
|
|
69
|
-
|
|
69
|
+
bool HKU_UTILS_API renameFile(const std::string &oldname, const std::string &newname,
|
|
70
|
+
bool overlay = false) noexcept;
|
|
70
71
|
|
|
71
72
|
/**
|
|
72
73
|
* 获取用户路径
|
|
73
74
|
*/
|
|
74
|
-
std::string
|
|
75
|
+
std::string HKU_UTILS_API getUserDir();
|
|
75
76
|
|
|
76
77
|
/**
|
|
77
78
|
* 获取程序当前所在路径
|
|
78
79
|
*/
|
|
79
|
-
std::string
|
|
80
|
+
std::string HKU_UTILS_API getCurrentDir();
|
|
80
81
|
|
|
81
82
|
/**
|
|
82
83
|
* 输出终端是否支持彩色控制字符
|
|
83
84
|
*/
|
|
84
|
-
bool
|
|
85
|
+
bool HKU_UTILS_API isColorTerminal() noexcept;
|
|
85
86
|
|
|
86
87
|
/**
|
|
87
88
|
* @brief 获取硬盘剩余存储空间大小
|
|
@@ -90,12 +91,12 @@ bool HKU_API isColorTerminal() noexcept;
|
|
|
90
91
|
* @param path 指定路径名
|
|
91
92
|
* @return uint64_t 获取失败时,返回 Null<uint64_t>()
|
|
92
93
|
*/
|
|
93
|
-
uint64_t
|
|
94
|
+
uint64_t HKU_UTILS_API getDiskFreeSpace(const char *path);
|
|
94
95
|
|
|
95
96
|
/** 获取当前系统名称 */
|
|
96
|
-
std::string
|
|
97
|
+
std::string HKU_UTILS_API getPlatform();
|
|
97
98
|
|
|
98
99
|
/** 获取当前CPU架构名称 */
|
|
99
|
-
std::string
|
|
100
|
+
std::string HKU_UTILS_API getCpuArch();
|
|
100
101
|
|
|
101
102
|
} // namespace hku
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright(C) 2021 hikyuu.org
|
|
3
|
+
*
|
|
4
|
+
* The code comes from: https://github.com/sniper00/snowflake-cpp
|
|
5
|
+
* Thanks sniper00
|
|
6
|
+
*
|
|
7
|
+
* Create on: 2021-04-13
|
|
8
|
+
* Author: fasiondog
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#pragma once
|
|
12
|
+
|
|
13
|
+
#include <cstdint>
|
|
14
|
+
#include <chrono>
|
|
15
|
+
#include <stdexcept>
|
|
16
|
+
#include <mutex>
|
|
17
|
+
|
|
18
|
+
namespace hku {
|
|
19
|
+
|
|
20
|
+
class snowflake_nonlock {
|
|
21
|
+
public:
|
|
22
|
+
void lock() {}
|
|
23
|
+
void unlock() {}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
template <int64_t Twepoch, typename Lock = snowflake_nonlock>
|
|
27
|
+
class snowflake {
|
|
28
|
+
using lock_type = Lock;
|
|
29
|
+
static constexpr int64_t TWEPOCH = Twepoch;
|
|
30
|
+
static constexpr int64_t WORKER_ID_BITS = 5L;
|
|
31
|
+
static constexpr int64_t DATACENTER_ID_BITS = 5L;
|
|
32
|
+
static constexpr int64_t MAX_WORKER_ID = (1 << WORKER_ID_BITS) - 1;
|
|
33
|
+
static constexpr int64_t MAX_DATACENTER_ID = (1 << DATACENTER_ID_BITS) - 1;
|
|
34
|
+
static constexpr int64_t SEQUENCE_BITS = 12L;
|
|
35
|
+
static constexpr int64_t WORKER_ID_SHIFT = SEQUENCE_BITS;
|
|
36
|
+
static constexpr int64_t DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
|
|
37
|
+
static constexpr int64_t TIMESTAMP_LEFT_SHIFT =
|
|
38
|
+
SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS;
|
|
39
|
+
static constexpr int64_t SEQUENCE_MASK = (1 << SEQUENCE_BITS) - 1;
|
|
40
|
+
|
|
41
|
+
using time_point = std::chrono::time_point<std::chrono::steady_clock>;
|
|
42
|
+
|
|
43
|
+
time_point start_time_point_ = std::chrono::steady_clock::now();
|
|
44
|
+
int64_t start_millsecond_ = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
45
|
+
std::chrono::system_clock::now().time_since_epoch())
|
|
46
|
+
.count();
|
|
47
|
+
|
|
48
|
+
int64_t last_timestamp_ = -1;
|
|
49
|
+
int64_t workerid_ = 0;
|
|
50
|
+
int64_t datacenterid_ = 0;
|
|
51
|
+
int64_t sequence_ = 0;
|
|
52
|
+
lock_type lock_;
|
|
53
|
+
|
|
54
|
+
public:
|
|
55
|
+
snowflake() = default;
|
|
56
|
+
|
|
57
|
+
snowflake(const snowflake&) = delete;
|
|
58
|
+
|
|
59
|
+
snowflake& operator=(const snowflake&) = delete;
|
|
60
|
+
|
|
61
|
+
void init(int64_t workerid, int64_t datacenterid) {
|
|
62
|
+
std::lock_guard<lock_type> lock(lock_);
|
|
63
|
+
if (workerid > MAX_WORKER_ID || workerid < 0) {
|
|
64
|
+
throw std::runtime_error("worker Id can't be greater than 31 or less than 0");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (datacenterid > MAX_DATACENTER_ID || datacenterid < 0) {
|
|
68
|
+
throw std::runtime_error("datacenter Id can't be greater than 31 or less than 0");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
workerid_ = workerid;
|
|
72
|
+
datacenterid_ = datacenterid;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
int64_t nextid() {
|
|
76
|
+
std::lock_guard<lock_type> lock(lock_);
|
|
77
|
+
// std::chrono::steady_clock cannot decrease as physical time moves forward
|
|
78
|
+
auto timestamp = millsecond();
|
|
79
|
+
if (last_timestamp_ == timestamp) {
|
|
80
|
+
sequence_ = (sequence_ + 1) & SEQUENCE_MASK;
|
|
81
|
+
if (sequence_ == 0) {
|
|
82
|
+
timestamp = wait_next_millis(last_timestamp_);
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
sequence_ = 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
last_timestamp_ = timestamp;
|
|
89
|
+
|
|
90
|
+
return ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) |
|
|
91
|
+
(datacenterid_ << DATACENTER_ID_SHIFT) | (workerid_ << WORKER_ID_SHIFT) | sequence_;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private:
|
|
95
|
+
int64_t millsecond() const {
|
|
96
|
+
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
97
|
+
std::chrono::steady_clock::now() - start_time_point_);
|
|
98
|
+
return start_millsecond_ + diff.count();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
int64_t wait_next_millis(int64_t last) const {
|
|
102
|
+
auto timestamp = millsecond();
|
|
103
|
+
while (timestamp <= last) {
|
|
104
|
+
timestamp = millsecond();
|
|
105
|
+
}
|
|
106
|
+
return timestamp;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
} // namespace hku
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2019~2021, hikyuu
|
|
3
|
+
*
|
|
4
|
+
* Created on: 2021/12/16
|
|
5
|
+
* Author: fasiondog
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include "cppdef.h"
|
|
11
|
+
|
|
12
|
+
#if CPP_STANDARD >= CPP_STANDARD_17
|
|
13
|
+
#include <string>
|
|
14
|
+
#include <string_view>
|
|
15
|
+
namespace hku {
|
|
16
|
+
|
|
17
|
+
using std::string_view;
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#else
|
|
22
|
+
|
|
23
|
+
#include <string>
|
|
24
|
+
#include <cstring>
|
|
25
|
+
#include "Log.h"
|
|
26
|
+
|
|
27
|
+
namespace hku {
|
|
28
|
+
|
|
29
|
+
class string_view {
|
|
30
|
+
public:
|
|
31
|
+
constexpr string_view() noexcept = default;
|
|
32
|
+
|
|
33
|
+
string_view(const char *data, std::size_t size) : _data(data), _size(size) {
|
|
34
|
+
HKU_CHECK_THROW(data, std::invalid_argument, "Input null ptr!");
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
string_view(const char *data) : _data(data) { // NOSONAR
|
|
38
|
+
HKU_CHECK_THROW(data, std::invalid_argument, "Input null ptr!");
|
|
39
|
+
_size = std::strlen(data);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
string_view(const std::string &str) : _data(str.data()), _size(str.size()) {} // NOSONAR
|
|
43
|
+
|
|
44
|
+
constexpr string_view(const string_view &) noexcept = default;
|
|
45
|
+
|
|
46
|
+
string_view &operator=(const string_view &) noexcept = default;
|
|
47
|
+
|
|
48
|
+
constexpr const char &operator[](std::size_t pos) const {
|
|
49
|
+
return _data[pos];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
constexpr const char *data() const noexcept {
|
|
53
|
+
return _data;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
constexpr std::size_t size() const noexcept {
|
|
57
|
+
return _size;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private:
|
|
61
|
+
constexpr string_view(std::nullptr_t) = delete;
|
|
62
|
+
|
|
63
|
+
private:
|
|
64
|
+
const char *_data = nullptr;
|
|
65
|
+
std::size_t _size = 0;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
} // namespace hku
|
|
69
|
+
|
|
70
|
+
#endif
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
#pragma GCC diagnostic push
|
|
23
23
|
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
24
24
|
#endif
|
|
25
|
-
#ifndef
|
|
26
|
-
#define
|
|
25
|
+
#ifndef HKU_UTILS_API
|
|
26
|
+
#define HKU_UTILS_API
|
|
27
27
|
#endif
|
|
28
28
|
|
|
29
29
|
namespace hku {
|
|
@@ -35,7 +35,7 @@ namespace hku {
|
|
|
35
35
|
#ifdef _MSC_VER
|
|
36
36
|
class MQStealThreadPool {
|
|
37
37
|
#else
|
|
38
|
-
class
|
|
38
|
+
class HKU_UTILS_API MQStealThreadPool {
|
|
39
39
|
#endif
|
|
40
40
|
public:
|
|
41
41
|
/**
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
24
24
|
#endif
|
|
25
25
|
|
|
26
|
-
#ifndef
|
|
27
|
-
#define
|
|
26
|
+
#ifndef HKU_UTILS_API
|
|
27
|
+
#define HKU_UTILS_API
|
|
28
28
|
#endif
|
|
29
29
|
|
|
30
30
|
namespace hku {
|
|
@@ -38,7 +38,7 @@ namespace hku {
|
|
|
38
38
|
#ifdef _MSC_VER
|
|
39
39
|
class MQThreadPool {
|
|
40
40
|
#else
|
|
41
|
-
class
|
|
41
|
+
class HKU_UTILS_API MQThreadPool {
|
|
42
42
|
#endif
|
|
43
43
|
public:
|
|
44
44
|
/**
|