Skip to content

Commit 08f3afb

Browse files
committed
feat(amuleapi): surface ed2k network user/file totals in /status + SSE
Symmetrical with the existing kad.network rollup — ed2k.network carries aggregate users and files across all connected servers so consumers can render an equivalent footer block for eD2k without guessing. No new EC round-trip: the daemon already ships EC_TAG_STATS_ED2K_{USERS,FILES} in every EC_OP_STAT_REQ response (ExternalConn.cpp:764-767), right next to the KAD_{USERS,FILES} tags we already parse. Wire the two tag reads into ParseStatusFromPacket, extend StatusSnapshot with matching fields, and emit them at the existing REST + SSE emit sites: - Refresher.cpp: parse EC_TAG_STATS_ED2K_USERS / _ED2K_FILES. - State.h: add ed2k_users / ed2k_files to StatusSnapshot. - Api.cpp HandleStatus: nest ed2k.network.{users,files} inside the existing ed2k object, mirroring kad.network's shape. - EventDiff.cpp ToJsonStatusEvent: emit the same keys so SSE status_changed reflects the values live. - EventDiff.cpp Equal(StatusSnapshot): compare the new fields — without this a change purely to the network totals wouldn't fire the status_changed event. Requested by @ngosang on PR #201 review.
1 parent f5da658 commit 08f3afb

4 files changed

Lines changed: 35 additions & 2 deletions

File tree

src/webapi/Api.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,17 @@ CHttpServer::Response CApiDispatcher::HandleStatus(const CHttpServer::Request &r
13931393
w.ValueString(wxString::FromUTF8(s.server_ip.c_str()));
13941394
w.Key("server_port");
13951395
w.ValueInt(static_cast<int64_t>(s.server_port));
1396+
// Network rollup, symmetric with kad.network below. Aggregate
1397+
// user + file counts across all connected ed2k servers, taken
1398+
// from the same EC_OP_STAT_REQ response the kad counters ride
1399+
// on — no extra round-trip.
1400+
w.Key("network");
1401+
w.BeginObject();
1402+
w.Key("users");
1403+
w.ValueInt(static_cast<int64_t>(s.ed2k_users));
1404+
w.Key("files");
1405+
w.ValueInt(static_cast<int64_t>(s.ed2k_files));
1406+
w.EndObject();
13961407
w.EndObject();
13971408

13981409
w.Key("kad");

src/webapi/EventDiff.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ std::string ToJsonStatusEvent(const StatusSnapshot &s, const KadSnapshot &k, boo
196196
<< ",\"low_id\":" << (s.ed2k_lowid ? "true" : "false") << ",\"server_name\":\""
197197
<< EscJson(s.server_name) << "\""
198198
<< ",\"server_ip\":\"" << EscJson(s.server_ip) << "\""
199-
<< ",\"server_port\":" << s.server_port << "}"
199+
<< ",\"server_port\":" << s.server_port << ",\"network\":{"
200+
<< "\"users\":" << s.ed2k_users << ",\"files\":" << s.ed2k_files << "}}"
200201
<< ",\"kad\":{"
201202
<< "\"state\":\"" << EscJson(s.kad_state) << "\""
202203
<< ",\"firewalled\":" << (s.kad_firewalled ? "true" : "false") << ",\"network\":{"
@@ -280,7 +281,8 @@ bool Equal(const StatusSnapshot &a, const StatusSnapshot &b)
280281
a.kad_firewalled == b.kad_firewalled && a.server_name == b.server_name &&
281282
a.server_ip == b.server_ip && a.server_port == b.server_port &&
282283
a.download_bps == b.download_bps && a.upload_bps == b.upload_bps &&
283-
a.ul_queue_len == b.ul_queue_len && a.total_src_count == b.total_src_count;
284+
a.ul_queue_len == b.ul_queue_len && a.total_src_count == b.total_src_count &&
285+
a.ed2k_users == b.ed2k_users && a.ed2k_files == b.ed2k_files;
284286
}
285287
bool Equal(const KadSnapshot &a, const KadSnapshot &b)
286288
{

src/webapi/Refresher.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,18 @@ void ParseStatusFromPacket(const CECPacket *resp, StatusSnapshot &out)
118118
if (const CECTag *t = resp->GetTagByName(EC_TAG_STATS_TOTAL_SRC_COUNT)) {
119119
out.total_src_count = static_cast<std::uint32_t>(t->GetInt());
120120
}
121+
// ed2k network aggregate — the same EC_OP_STAT_REQ response
122+
// already carries KAD_USERS / KAD_FILES (parsed further down in
123+
// ParseKadFromPacket), plus ED2K_USERS / ED2K_FILES sitting right
124+
// next to them (ExternalConn.cpp:762-768). Read them here so
125+
// /status can surface ed2k.network.{users,files} symmetric with
126+
// kad.network.{users,files,nodes} — no extra EC round-trip.
127+
if (const CECTag *t = resp->GetTagByName(EC_TAG_STATS_ED2K_USERS)) {
128+
out.ed2k_users = static_cast<std::uint32_t>(t->GetInt());
129+
}
130+
if (const CECTag *t = resp->GetTagByName(EC_TAG_STATS_ED2K_FILES)) {
131+
out.ed2k_files = static_cast<std::uint32_t>(t->GetInt());
132+
}
121133
// Nickname intentionally absent: it isn't shipped in the
122134
// EC_OP_STAT_REQ response. amuled returns it from
123135
// EC_OP_GET_PREFERENCES / EC_OP_GET_STATSTREE@DETAIL_WEB; the

src/webapi/State.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,14 @@ struct StatusSnapshot
448448
// Aggregate counts pulled by the same EC_OP_STATS round-trip.
449449
std::uint32_t ul_queue_len = 0;
450450
std::uint32_t total_src_count = 0;
451+
452+
// ed2k network-wide totals (all connected servers). Surfaced in
453+
// /status as ed2k.network.{users,files} — symmetric with
454+
// kad.network.{users,files,nodes} on KadSnapshot. Populated from
455+
// EC_TAG_STATS_ED2K_{USERS,FILES}, present in the same
456+
// EC_OP_STAT_REQ response we already parse.
457+
std::uint32_t ed2k_users = 0;
458+
std::uint32_t ed2k_files = 0;
451459
};
452460

453461
// ECID-keyed file map + hash→ECID index in lockstep. The index is

0 commit comments

Comments
 (0)