refactors

This commit is contained in:
Takanashi Hoshino
2026-09-13 12:04:37 +08:00
parent c478367c6c
commit ddfd680301
15 changed files with 196 additions and 651 deletions
+42 -22
View File
@@ -148,7 +148,7 @@ const processCookieObject = (cookie, crypto) => {
if (!processedCookie.MUSIC_U) {
processedCookie.MUSIC_A =
processedCookie.MUSIC_A || runtimeState.getAnonymousToken()
processedCookie.MUSIC_A || runtimeState.anonymousToken
}
return processedCookie
@@ -175,6 +175,33 @@ const generateRequestId = () => {
.padStart(4, '0')}`
}
// ---- 运行时凭证的强制刷新 ----
// 匿名令牌与 xeapi 公钥存于 util/runtimeState(纯内存、零文件 I/O),
// 由对应的 register_* 模块在成功获取后写入,此处只负责编排调用。
// 刷新自身的请求带 skipTokenEnsure 标记:跳过下方匿名令牌的按需引导,
// 避免“刷新任务等待自己”的死锁(注册匿名账号本就不依赖旧令牌)
const refreshTokenRequest = (uri, data, options = {}) =>
createRequest(uri, data, { ...options, skipTokenEnsure: true })
// 强制刷新匿名令牌(成功后由 register_anonimous 写入 runtimeState)
const refreshAnonymousToken = async () => {
const registerAnonimous = require('../module/register_anonimous')
await registerAnonimous({}, refreshTokenRequest)
}
// 强制刷新 xeapi 公钥(register_xeapikey 直接走 axios,无重入问题;
// 成功后由其写入 runtimeState)
const refreshXeapiPublicKey = async () => {
const registerXeapikey = require('../module/register_xeapikey')
await registerXeapikey(
{
currentKeyVersion: (runtimeState.xeapiPublicKey || {}).version || '',
},
null,
)
}
const createRequest = async (uri, data, options) => {
let token = ''
switch (options.checkToken) {
@@ -188,37 +215,27 @@ const createRequest = async (uri, data, options) => {
break
}
// 懒加载匿名 token:仅当内存中缺失时刷新一次,失败不阻塞本次请求。
// 兼容 serverless 冷启动——不假设启动阶段已刷新过。
// 刷新类请求自身跳过(否则会等待自己造成死锁)。
if (
!runtimeState.getAnonymousToken() &&
!runtimeState.isAnonymousTokenRefreshing()
) {
// 匿名令牌缺失时按需引导:并发请求共享同一次刷新任务;
// 刷新自身的请求(skipTokenEnsure)跳过,避免任务等待自己造成死锁
if (!runtimeState.anonymousToken && !options.skipTokenEnsure) {
try {
const { ensureAnonymousToken } = require('./credentials')
await ensureAnonymousToken()
await runtimeState.ensure('anonymousToken', refreshAnonymousToken)
} catch (error) {
console.log('[ERR]', error)
}
}
// 懒加载 xeapi public key:仅在本次请求确实使用 xeapi 加密、且内存缺失时刷新。
// 必须在进入同步 executor 前完成,因为加密过程需要同步拿到本状态。
const resolvedCrypto =
options.crypto === '' || options.crypto === undefined
// 本请求走 xeapi 加密且公钥缺失时按需获取
// (须在进入下方同步 executor 前完成,加密过程需要同步拿到公钥)
const pendingCrypto =
options.crypto === undefined || options.crypto === ''
? APP_CONF.encrypt
? 'eapi'
: 'api'
: options.crypto
if (
resolvedCrypto === 'xeapi' &&
!runtimeState.getXeapiPublicKey() &&
!runtimeState.isXeapiPublicKeyRefreshing()
) {
if (pendingCrypto === 'xeapi' && !runtimeState.xeapiPublicKey) {
try {
const { ensureXeapiPublicKey } = require('./credentials')
await ensureXeapiPublicKey()
await runtimeState.ensure('xeapiPublicKey', refreshXeapiPublicKey)
} catch (error) {
console.log('[ERR]', error)
}
@@ -288,7 +305,7 @@ const createRequest = async (uri, data, options) => {
break
case 'xeapi':
const xeapiPublicKey = runtimeState.getXeapiPublicKey()
const xeapiPublicKey = runtimeState.xeapiPublicKey
if (!xeapiPublicKey) {
throw new Error('xeapi public key is missing')
}
@@ -531,3 +548,6 @@ const createRequest = async (uri, data, options) => {
}
module.exports = createRequest
// 供 generateConfig 等复用的强制刷新入口(成功后写入 runtimeState)
module.exports.refreshAnonymousToken = refreshAnonymousToken
module.exports.refreshXeapiPublicKey = refreshXeapiPublicKey