mirror of
https://github.com/kuaifan/dootask.git
synced 2026-10-29 22:10:42 +00:00
fix(manticore): 同步命令读增量指针改用严格读取,引擎不可达时终止而非从头重灌
ManticoreKeyValue::get() 在引擎重启/不可达时返回默认值 0,导致增量同步从头重灌 并把指针写回低值,引发 AI 插件向量化风暴。新增 getStrict()/queryOneStrict(), 读取失败抛异常,五个同步命令据此终止本轮。
This commit is contained in:
parent
621017c0c6
commit
8bb169b4d0
@ -74,7 +74,13 @@ class SyncFileToManticore extends Command
|
||||
|
||||
do {
|
||||
$round++;
|
||||
$lastId = $isIncremental ? intval(ManticoreKeyValue::get($lastKey, 0)) : 0;
|
||||
try {
|
||||
// 严格读取:读失败(引擎重启/不可达)不能当成 0,否则会从头重灌并把指针写回低值
|
||||
$lastId = $isIncremental ? intval(ManticoreKeyValue::getStrict($lastKey)) : 0;
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->error("读取同步指针失败,本轮终止(避免从头重灌):" . $e->getMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
if ($round === 1) {
|
||||
if ($lastId > 0) {
|
||||
|
||||
@ -81,7 +81,13 @@ class SyncMsgToManticore extends Command
|
||||
// 持续处理循环(增量模式下)
|
||||
do {
|
||||
$round++;
|
||||
$lastId = $isIncremental ? intval(ManticoreKeyValue::get($lastKey, 0)) : 0;
|
||||
try {
|
||||
// 严格读取:读失败(引擎重启/不可达)不能当成 0,否则会从头重灌并把指针写回低值
|
||||
$lastId = $isIncremental ? intval(ManticoreKeyValue::getStrict($lastKey)) : 0;
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->error("读取同步指针失败,本轮终止(避免从头重灌):" . $e->getMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
if ($round === 1) {
|
||||
if ($lastId > 0) {
|
||||
|
||||
@ -68,7 +68,13 @@ class SyncProjectToManticore extends Command
|
||||
|
||||
do {
|
||||
$round++;
|
||||
$lastId = $isIncremental ? intval(ManticoreKeyValue::get($lastKey, 0)) : 0;
|
||||
try {
|
||||
// 严格读取:读失败(引擎重启/不可达)不能当成 0,否则会从头重灌并把指针写回低值
|
||||
$lastId = $isIncremental ? intval(ManticoreKeyValue::getStrict($lastKey)) : 0;
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->error("读取同步指针失败,本轮终止(避免从头重灌):" . $e->getMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
if ($round === 1) {
|
||||
if ($lastId > 0) {
|
||||
|
||||
@ -68,7 +68,13 @@ class SyncTaskToManticore extends Command
|
||||
|
||||
do {
|
||||
$round++;
|
||||
$lastId = $isIncremental ? intval(ManticoreKeyValue::get($lastKey, 0)) : 0;
|
||||
try {
|
||||
// 严格读取:读失败(引擎重启/不可达)不能当成 0,否则会从头重灌并把指针写回低值
|
||||
$lastId = $isIncremental ? intval(ManticoreKeyValue::getStrict($lastKey)) : 0;
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->error("读取同步指针失败,本轮终止(避免从头重灌):" . $e->getMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
if ($round === 1) {
|
||||
if ($lastId > 0) {
|
||||
|
||||
@ -68,7 +68,13 @@ class SyncUserToManticore extends Command
|
||||
|
||||
do {
|
||||
$round++;
|
||||
$lastId = $isIncremental ? intval(ManticoreKeyValue::get($lastKey, 0)) : 0;
|
||||
try {
|
||||
// 严格读取:读失败(引擎重启/不可达)不能当成 0,否则会从头重灌并把指针写回低值
|
||||
$lastId = $isIncremental ? intval(ManticoreKeyValue::getStrict($lastKey)) : 0;
|
||||
} catch (\RuntimeException $e) {
|
||||
$this->error("读取同步指针失败,本轮终止(避免从头重灌):" . $e->getMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
if ($round === 1) {
|
||||
if ($lastId > 0) {
|
||||
|
||||
@ -598,6 +598,37 @@ class ManticoreBase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单行(严格版):连接/查询失败抛异常,而不是和「没有这一行」一样返回 null
|
||||
*
|
||||
* 用于「读不到就当默认值」会造成后果的场景,如同步命令读增量指针——
|
||||
* 引擎不可达时若当成指针 0,会从头重灌全部数据。
|
||||
*
|
||||
* @param string $sql SQL语句
|
||||
* @param array $params 参数
|
||||
* @return array|null 单行结果;没有匹配行返回 null
|
||||
* @throws \RuntimeException 连接或查询失败
|
||||
*/
|
||||
public function queryOneStrict(string $sql, array $params = []): ?array
|
||||
{
|
||||
$failed = new \stdClass();
|
||||
$result = $this->runWithRetry(
|
||||
function (PDO $pdo) use ($sql, $params) {
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$this->bindParams($stmt, $params);
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch();
|
||||
return $row ? $this->convertNumericTypesRow($row) : null;
|
||||
},
|
||||
$failed,
|
||||
['sql' => $sql, 'params' => $params]
|
||||
);
|
||||
if ($result === $failed) {
|
||||
throw new \RuntimeException('Manticore 不可达或查询失败');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换结果集中的数值类型
|
||||
* PDO 默认将 BIGINT 等数值类型返回为字符串,这里统一转换
|
||||
|
||||
@ -34,6 +34,31 @@ class ManticoreKeyValue
|
||||
return $result ? $result['v'] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* 严格获取值:键不存在返回 null,引擎不可达/查询失败抛异常
|
||||
*
|
||||
* get() 对「键不存在」和「读取失败」都返回默认值,无法区分。同步命令用它读增量指针:
|
||||
* 引擎重启期间读失败若当成 0,会从头重灌全部数据并把指针写回低值。
|
||||
*
|
||||
* @param string $key 键
|
||||
* @return string|null 值;键不存在返回 null
|
||||
* @throws \RuntimeException 引擎不可达或查询失败
|
||||
*/
|
||||
public static function getStrict(string $key): ?string
|
||||
{
|
||||
if (!Apps::isInstalled("search")) {
|
||||
throw new \RuntimeException('Manticore Search 未安装');
|
||||
}
|
||||
|
||||
$instance = new ManticoreBase();
|
||||
$result = $instance->queryOneStrict(
|
||||
"SELECT v FROM key_values WHERE k = ?",
|
||||
[$key]
|
||||
);
|
||||
|
||||
return $result ? (string) $result['v'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置值
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user