fix(ncm): 缓存命中改单请求出参,移除全局命中计数(评审 P2-2/P2-1)
问题(P2-2):离线判定用 `ncm_apicache_hits()` 前后差值判「本次是否缓存命中」—— ①其它 worker 的命中会污染差值 → 误判「已回在线」;②盘缓存分支的 g_hits++ 在 g_mu 锁外, 跨线程自增/64 位读存在竞争与撕裂可能。 修法(出参方案): - `api_post_cached(..., int *from_cache)`:命中置 1(未走网络),miss/失败为 0; 四个调用点显式传参。 - 新增 `ncm_api_user_playlist_ex(..., int *out_from_cache)`;out_n 与原接口一致**必填** (NULL→NCM_ERR_ARG,修入口容忍 NULL、成功路径却无条件解引用的契约不一致,评审 P2-1); out_from_cache 可 NULL。旧 `ncm_api_user_playlist` 为薄包装(调用方零改动)。 - `appstate_load_playlists_ex` 透传该标志;home_worker 用本次请求的 from_cache 判定是否 回在线;歌单页只在失败时同步离线态(成功可能是缓存命中,不据此清离线)。 - 删除 `ncm_apicache_hits()`/g_hits(无使用者,同时消除数据竞争);盘缓存命中分支两行 合并为一行(行为不变,重构)。 - 测试:session_gate_sim 新增 D2 五例(miss→0 且真网络 +1 次 / 命中→1 且 0 请求 / 失败→0 / 兼容入口不崩 / out_n 必填契约);playlist_race_sim、plpage_sim 补 `_ex` 桩。 验证:session_gate_sim 88 PASS/0 FAIL;test_ncm_core_host 139 PASS/0 FAIL; http_truncate_sim 13 PASS/0 FAIL;核心 13 TU(-Wall -Wextra)0 warning。
This commit is contained in:
1 parent
b1d607d43f
commit
31879f3302
12 files changed
+134
-49
No files matched your search
@@ -9,6 +9,9 @@
|
||||
* D. 真实 ncm_api(ncm_http_request 桩)HTTP 状态与业务码映射:
|
||||
* 401/403 与业务 301/302 → AUTH(退登录);5xx/429、业务 -460 → SVC(保登录态/离线);
|
||||
* HTML 体 → JSON(other);其它业务码 → HTTP(other)。
|
||||
* D2. `ncm_api_user_playlist_ex` 的 from_cache 出参:miss→0(真网络 +1 次)、命中→1(0 请求)、
|
||||
* 失败→0;兼容入口不崩;out_n 必填契约(NULL→NCM_ERR_ARG)(离线判定不得用全局计数,
|
||||
* 评审 P2-2/P2-1)。
|
||||
* E. 真实 ncm_login_status_check / ncm_login_refresh 同上(AUTH 只在服务端明确否定时)。
|
||||
* F. 会话加密密钥稳定性(M9 根因回归):session.enc 保存后改变网卡 MAC(NCM_MAC 桩)仍能解出
|
||||
* cookie;旧版 MAC 派生密文可解且自动迁移到 .mkey 密钥。
|
||||
@@ -259,6 +262,51 @@ static void test_api_map(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* D2. user_playlist_ex:本次结果是否来自接口缓存(评审 P2-2)
|
||||
* ============================================================ */
|
||||
static void test_api_from_cache(void)
|
||||
{
|
||||
printf("== D2. ncm_api_user_playlist_ex 缓存命中出参(离线判定用)==\n");
|
||||
ncm_apicache_init(NULL);
|
||||
ncm_apicache_clear();
|
||||
const char *body = "{\"code\":200,\"playlist\":[{\"id\":1,\"name\":\"a\",\"trackCount\":1}]}";
|
||||
ncm_playlist_t pls[4];
|
||||
int n = 0, fc = -1, rc;
|
||||
|
||||
stub(200, body, NULL);
|
||||
int calls0 = g_http_calls;
|
||||
rc = ncm_api_user_playlist_ex("dev", "MUSIC_U=x", "1", 30, 0, pls, 4, &n, &fc);
|
||||
CHECK(rc == NCM_OK && fc == 0 && g_http_calls == calls0 + 1 && n == 1,
|
||||
"首次(缓存 miss):rc=0 n=%d from_cache=%d,真网络 +1 次(calls %d→%d)",
|
||||
n, fc, calls0, g_http_calls);
|
||||
|
||||
fc = -1;
|
||||
calls0 = g_http_calls;
|
||||
rc = ncm_api_user_playlist_ex("dev", "MUSIC_U=x", "1", 30, 0, pls, 4, &n, &fc);
|
||||
CHECK(rc == NCM_OK && fc == 1 && g_http_calls == calls0 && n == 1,
|
||||
"二次同参(缓存命中):rc=0 from_cache=%d,未发网络请求(calls=%d)",
|
||||
fc, g_http_calls);
|
||||
|
||||
/* 失败不得把 from_cache 留成 1(App 会据此判离线,方向必须正确) */
|
||||
ncm_apicache_clear();
|
||||
stub_err(NCM_ERR_NET);
|
||||
fc = -1;
|
||||
rc = ncm_api_user_playlist_ex("dev", "MUSIC_U=x", "1", 30, 0, pls, 4, &n, &fc);
|
||||
CHECK(rc == NCM_ERR_NET && fc == 0, "网络失败:rc=%d from_cache=%d(期望 -4/0)", rc, fc);
|
||||
|
||||
/* 兼容入口仍可用(out_from_cache=NULL 不崩) */
|
||||
ncm_apicache_clear();
|
||||
stub(200, body, NULL);
|
||||
rc = ncm_api_user_playlist("dev", "MUSIC_U=x", "1", 30, 0, pls, 4, &n);
|
||||
CHECK(rc == NCM_OK && n == 1, "兼容入口 ncm_api_user_playlist 正常(rc=%d n=%d)", rc, n);
|
||||
|
||||
/* 契约:out_n 必填(与原接口一致);out_from_cache 可 NULL(评审 P2-1) */
|
||||
rc = ncm_api_user_playlist_ex("dev", "MUSIC_U=x", "1", 30, 0, pls, 4, NULL, &fc);
|
||||
CHECK(rc == NCM_ERR_ARG, "out_n=NULL → NCM_ERR_ARG(契约与原接口一致)rc=%d", rc);
|
||||
ncm_apicache_clear();
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* E. 真实 ncm_login:cookie 校验 / 续期
|
||||
* ============================================================ */
|
||||
@@ -414,6 +462,7 @@ int main(void)
|
||||
test_http_class();
|
||||
test_gate();
|
||||
test_api_map();
|
||||
test_api_from_cache();
|
||||
test_login_map();
|
||||
test_session_key_stability();
|
||||
printf("\n== SESSION GATE SIM: %s (http stubs called %d times) ==\n",
|
||||
|
||||
Reference in new issue
Block a user