Skip to content

Commit 80c6923

Browse files
Merge pull request #125 from aethernetio/124-collect-all-ping-values-and-count-statistics
124 collect all ping values and count statistics
2 parents bd172ba + c2f1af1 commit 80c6923

25 files changed

Lines changed: 419 additions & 201 deletions

File tree

.github/workflows/ci-cd-multi-platforms.yml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,13 @@ jobs:
8282
platforms:
8383
- {
8484
name: "Hydrogen",
85-
user_config: "../config/user_config_hydrogen.h",
86-
fs_init: "../../../../config/file_system_init.h",
85+
user_config: "./config/user_config_hydrogen.h",
86+
fs_init: "./config/file_system_init.h",
8787
}
8888
- {
8989
name: "Sodium",
90-
user_config: "../config/user_config_sodium.h",
91-
fs_init: "../../../../config/file_system_init.h",
90+
user_config: "./config/user_config_sodium.h",
91+
fs_init: "./config/file_system_init.h",
9292
}
9393

9494
steps:
@@ -138,6 +138,8 @@ jobs:
138138
git apply "../libhydrogen.patch"
139139
cd ../libsodium
140140
git apply "../libsodium.patch"
141+
cd ../etl
142+
git apply "../etl.patch"
141143
cd ../
142144
cp "CMakeLists.libbcrypt" "libbcrypt/CMakeLists.txt"
143145
cp "CMakeLists.libhydrogen" "libhydrogen/CMakeLists.txt"
@@ -192,8 +194,8 @@ jobs:
192194
platforms:
193195
- {
194196
name: "Optimized",
195-
user_config: "../config/user_config_optimized.h",
196-
fs_init: "../../../../config/file_system_init.h",
197+
user_config: "./config/user_config_optimized.h",
198+
fs_init: "./config/file_system_init.h",
197199
}
198200

199201
steps:
@@ -212,6 +214,8 @@ jobs:
212214
git apply "../libhydrogen.patch"
213215
cd ../libsodium
214216
git apply "../libsodium.patch"
217+
cd ../etl
218+
git apply "../etl.patch"
215219
cd ../
216220
cp "CMakeLists.libbcrypt" "libbcrypt/CMakeLists.txt"
217221
cp "CMakeLists.libhydrogen" "libhydrogen/CMakeLists.txt"
@@ -227,8 +231,8 @@ jobs:
227231
path: "projects/xtensa_lx6/vscode/aether-client-cpp"
228232
command: idf.py build
229233
-DCOMPILE_EXAMPLE=${{ matrix.compile_example }}
230-
-DUSER_CONFIG=${{ matrix.platforms.user_config }}
231-
-DFS_INIT="${{ matrix.platforms.fs_init }}"
234+
-DUSER_CONFIG=../../../../../${{ matrix.platforms.user_config }}
235+
-DFS_INIT="../../../../../${{ matrix.platforms.fs_init }}"
232236
-DAE_DISTILLATION=Off
233237

234238
- name: Rename artifact

.gitmodules

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,10 @@
5050
path = third_party/ini.h
5151
url = https://github.com/giosali/ini.h
5252
branch = main
53-
ignore = dirty
53+
ignore = dirty
54+
55+
[submodule "third_party/etl"]
56+
path = third_party/etl
57+
url = https://github.com/ETLCPP/etl.git
58+
branch = master
59+
ignore = dirty

aether/CMakeLists.txt

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,22 @@ set(AE_PROJECT_VERSION "1.0.0")
1919
option(AE_NO_STRIP_ALL "Do not apply --strip_all, useful for bloaty and similar tools " Off)
2020

2121
option(AE_DISTILLATION "Build aether in distillation mode" OFF)
22-
option(USER_CONFIG "Path to user provided configuration header file" "")
2322

24-
find_program(GIT_COMMAND git)
25-
if ( GIT_COMMAND )
26-
# get current git version
27-
execute_process(
28-
COMMAND ${GIT_COMMAND} -C ${CMAKE_CURRENT_SOURCE_DIR} rev-parse --verify HEAD
29-
OUTPUT_VARIABLE GIT_VERSION
30-
)
31-
if ( NOT GIT_VERSION )
32-
message(WARNING "Not a git repo")
33-
else()
34-
string(STRIP ${GIT_VERSION} GIT_VERSION)
35-
message(STATUS "get aether git version ${GIT_VERSION}")
36-
endif()
37-
endif()
23+
set(USER_CONFIG "" CACHE PATH "Path to user provided configuration header file")
24+
set(FS_INIT "" CACHE PATH "Path to user provided saved state header file")
3825

3926
# list a common dependencies
4027
list(APPEND common_dependencies
4128
"../third_party/libbcrypt"
4229
"../third_party/libhydrogen"
4330
"../third_party/libsodium"
4431
"../third_party/gcem"
32+
"../third_party/etl"
4533
)
4634

35+
# for etl
36+
set(GIT_DIR_LOOKUP_POLICY ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
37+
4738
list(APPEND aether_srcs
4839
"aether_app.cpp"
4940
"aether.cpp"
@@ -55,7 +46,6 @@ list(APPEND aether_srcs
5546
"registration_cloud.cpp"
5647
"work_cloud.cpp"
5748
"server.cpp"
58-
"statistics.cpp"
5949
"uid.cpp"
6050
"proof_of_work.cpp"
6151
"server_keys.cpp"
@@ -206,20 +196,21 @@ list(APPEND port_srcs
206196
"port/file_systems/drivers/driver_header.cpp"
207197
"port/file_systems/drivers/driver_spifs.cpp")
208198

199+
list(APPEND statistics_srcs
200+
"statistics/channel_statistics.cpp")
201+
209202
list(APPEND tele_srcs
210203
"tele/traps/io_stream_traps.cpp"
211204
"tele/traps/statistics_trap.cpp"
212205
"tele/traps/tele_statistics.cpp")
213206

214207
message(STATUS "Cmake system name is ${CMAKE_SYSTEM_NAME}")
215208

216-
if(NOT CM_PLATFORM AND (
217-
CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
218-
CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
219-
CMAKE_SYSTEM_NAME STREQUAL "Windows" OR
220-
CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
221-
message(STATUS "Build for regular cmake project")
209+
if(NOT CM_PLATFORM)
210+
message(STATUS "Aether build for regular cmake project")
222211
set(REGULAR_CMAKE_PROJECT On)
212+
else()
213+
message(STATUS "Aether build for CM_PLATFORM=${CM_PLATFORM}")
223214
endif()
224215

225216
if(REGULAR_CMAKE_PROJECT)
@@ -252,6 +243,7 @@ if(REGULAR_CMAKE_PROJECT)
252243
${client_messages_srcs}
253244
${client_connections_srcs}
254245
${port_srcs}
246+
${statistics_srcs}
255247
${tele_srcs}
256248
)
257249

@@ -264,7 +256,8 @@ if(REGULAR_CMAKE_PROJECT)
264256
bcrypt
265257
sodium
266258
hydrogen
267-
gcem)
259+
gcem
260+
etl)
268261
target_link_libraries(${PROJECT_NAME} PRIVATE c-ares )
269262

270263
set(TARGET_NAME "${PROJECT_NAME}")
@@ -292,6 +285,7 @@ else()
292285
${client_messages_srcs}
293286
${client_connections_srcs}
294287
${port_srcs}
288+
${statistics_srcs}
295289
${tele_srcs}
296290
INCLUDE_DIRS ${include_dirs}
297291
REQUIRES esp_wifi nvs_flash spiffs)
@@ -307,7 +301,8 @@ else()
307301
bcrypt
308302
sodium
309303
hydrogen
310-
gcem)
304+
gcem
305+
etl)
311306
else()
312307
#ERROR
313308
message(SEND_ERROR "You must specify the CMAKE version!")
@@ -325,24 +320,40 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
325320
target_link_libraries(${TARGET_NAME} PRIVATE ws2_32)
326321
endif()
327322

323+
find_program(GIT_COMMAND git)
324+
if ( GIT_COMMAND )
325+
# get current git version
326+
execute_process(
327+
COMMAND ${GIT_COMMAND} -C ${CMAKE_CURRENT_SOURCE_DIR} rev-parse --verify HEAD
328+
OUTPUT_VARIABLE GIT_VERSION
329+
)
330+
if ( NOT GIT_VERSION )
331+
message(WARNING "Not a git repo")
332+
else()
333+
string(STRIP ${GIT_VERSION} GIT_VERSION)
334+
message(STATUS "get aether git version ${GIT_VERSION}")
335+
endif()
336+
endif()
337+
328338
if (GIT_VERSION)
329339
target_compile_definitions(${TARGET_NAME} PUBLIC "AE_GIT_VERSION=\"${GIT_VERSION}\"")
330340
endif()
331341
target_compile_definitions(${TARGET_NAME} PUBLIC "AE_PROJECT_VERSION=\"${AE_PROJECT_VERSION}\"")
332342

333-
if (USER_CONFIG)
343+
if (NOT "${USER_CONFIG}" STREQUAL "")
334344
target_compile_definitions(${TARGET_NAME} PUBLIC "USER_CONFIG=\"${USER_CONFIG}\"")
335345
endif()
336346

337-
if (FS_INIT)
347+
if (NOT "${FS_INIT}" STREQUAL "")
338348
target_compile_definitions(${TARGET_NAME} PUBLIC "FS_INIT=\"${FS_INIT}\"")
339349
endif()
340350

341351
if (AE_DISTILLATION)
342352
target_compile_definitions(${TARGET_NAME} PUBLIC "AE_DISTILLATION=1")
343353
endif()
344354

345-
if(_AE_REG_CLOUD_IP)
355+
# for debug purposes only, set registration server ip address
356+
if(NOT "${_AE_REG_CLOUD_IP}" STREQUAL "")
346357
target_compile_definitions(${TARGET_NAME} PUBLIC "_AE_REG_CLOUD_IP=\"${_AE_REG_CLOUD_IP}\"")
347358
endif()
348359

aether/ae_actions/ae_actions_tele.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,7 @@ AE_TAG(kGetClientCloudConnectionServerListIsOver, kAeActions)
5656
AE_TAG(kPing, kAeActions)
5757
AE_TAG(kPingSend, kAeActions)
5858
AE_TAG(kPingWriteError, kAeActions)
59+
AE_TAG(kPingTimeout, kAeActions)
60+
AE_TAG(kPingTimeoutError, kAeActions)
5961

6062
#endif // AETHER_AE_ACTIONS_AE_ACTIONS_TELE_H_

aether/ae_actions/ping.cpp

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "aether/ae_actions/ping.h"
1818

1919
#include <utility>
20+
#include <optional>
2021

2122
#include "aether/api_protocol/packet_builder.h"
2223
#include "aether/methods/work_server_api/authorized_api.h"
@@ -33,6 +34,7 @@ Ping::Ping(ActionContext action_context, Server::ptr const& server,
3334
server_stream_{&server_stream},
3435
ping_interval_{ping_interval},
3536
read_client_safe_api_gate_{protocol_context_, client_safe_api_},
37+
repeat_count_{},
3638
state_{State::kWaitLink},
3739
state_changed_sub_{state_.changed_event().Subscribe(
3840
[this](auto) { Action::Trigger(); })},
@@ -56,8 +58,7 @@ TimePoint Ping::Update(TimePoint current_time) {
5658
case State::kSendPing:
5759
SendPing(current_time);
5860
break;
59-
case State::kWaitResponse: // TODO: response timeout and response
60-
// statistics
61+
case State::kWaitResponse:
6162
case State::kWaitInterval:
6263
break;
6364
case State::kError:
@@ -66,21 +67,20 @@ TimePoint Ping::Update(TimePoint current_time) {
6667
}
6768
}
6869

70+
if (state_.get() == State::kWaitResponse) {
71+
return WaitResponse(current_time);
72+
}
6973
if (state_.get() == State::kWaitInterval) {
70-
if ((last_ping_time_ + ping_interval_) <= current_time) {
71-
state_ = State::kSendPing;
72-
} else {
73-
return last_ping_time_ + ping_interval_;
74-
}
74+
return WaitInterval(current_time);
7575
}
7676

7777
return current_time;
7878
}
7979

8080
void Ping::SendPing(TimePoint current_time) {
8181
AE_TELE_DEBUG(kPingSend, "Send ping");
82-
last_ping_time_ = current_time;
8382
auto request_id = RequestId::GenRequestId();
83+
ping_times_.push(std::make_pair(request_id, current_time));
8484
auto packet = PacketBuilder{
8585
protocol_context_,
8686
PackMessage{AuthorizedApi{},
@@ -100,18 +100,69 @@ void Ping::SendPing(TimePoint current_time) {
100100
});
101101

102102
// Wait for response
103-
SendResult::OnResponse(protocol_context_, request_id,
104-
[&](ApiParser&) { PingResponse(); });
103+
SendResult::OnResponse(
104+
protocol_context_, request_id,
105+
[&, req_id{request_id}](ApiParser&) { PingResponse(req_id); });
105106

106107
state_ = State::kWaitResponse;
107108
}
108109

109-
void Ping::PingResponse() {
110+
TimePoint Ping::WaitInterval(TimePoint current_time) {
111+
auto const& ping_time = ping_times_.back().second;
112+
if ((ping_time + ping_interval_) > current_time) {
113+
return ping_time + ping_interval_;
114+
}
115+
state_ = State::kSendPing;
116+
return current_time;
117+
}
118+
119+
TimePoint Ping::WaitResponse(TimePoint current_time) {
120+
auto channel_ptr = channel_.Lock();
121+
assert(channel_ptr);
122+
auto timeout = channel_ptr->expected_ping_time();
123+
124+
auto const& ping_time = ping_times_.back().second;
125+
if ((ping_time + timeout) > current_time) {
126+
return ping_time + timeout;
127+
}
128+
// timeout
129+
AE_TELE_INFO(kPingTimeout, "Timeout is {:%S}", timeout);
130+
if (repeat_count_ >= kMaxRepeatPingCount) {
131+
AE_TELE_ERROR(kPingTimeoutError, "Ping repeat count exceeded");
132+
state_ = State::kError;
133+
} else {
134+
repeat_count_++;
135+
state_ = State::kSendPing;
136+
}
137+
138+
return current_time;
139+
}
140+
141+
void Ping::PingResponse(RequestId request_id) {
142+
auto request_time = [&]() -> std::optional<TimePoint> {
143+
for (auto const& [req_id, time] : ping_times_) {
144+
if (req_id == request_id) {
145+
return time;
146+
}
147+
}
148+
return std::nullopt;
149+
}();
150+
151+
if (!request_time) {
152+
AE_TELED_DEBUG("Got lost, or not our ping request");
153+
return;
154+
}
155+
156+
repeat_count_ = 0;
110157
auto current_time = Now();
111158
auto ping_duration =
112-
std::chrono::duration_cast<Duration>(current_time - last_ping_time_);
159+
std::chrono::duration_cast<Duration>(current_time - *request_time);
113160

114161
AE_TELED_DEBUG("Ping received by {:%S} s", ping_duration);
162+
auto channel_ptr = channel_.Lock();
163+
assert(channel_ptr);
164+
channel_ptr->AddPingTime(ping_duration);
165+
115166
state_ = State::kWaitInterval;
116167
}
117168

0 commit comments

Comments
 (0)