Read article node counts from the published v2 release
This commit is contained in:
parent
568aa9e4b8
commit
cc9d1444a3
@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Services;
|
||||
use App\Models\FreenodePool;
|
||||
use App\Services\Freenode\Pipeline;
|
||||
use RuntimeException;
|
||||
|
||||
final class CountrySpeedService
|
||||
{
|
||||
@ -60,16 +62,35 @@ final class CountrySpeedService
|
||||
//// 速度
|
||||
$iNodeSpeed = rand(config("freenode.speed_min"), config("freenode.speed_max"));
|
||||
|
||||
$oFnp = FreenodePool::whereDate('date', date("Y-m-d"))->first();
|
||||
// var_dump($oFnp->id);exit;
|
||||
$aFnpContent = json_decode($oFnp->content ?? '[]', true); // 有问题吗
|
||||
$iNodeCount = count($aFnpContent["v2ray"] ?? []) ?? rand(30, 98);
|
||||
// $iNodeCount = rand(config("freenode.count_min"), config("freenode.count_max"));
|
||||
$iNodeCount = self::nodeCount();
|
||||
|
||||
$sContent = "本次更新共<b style='color:pink'>".$iNodeCount."</b>个可用节点,最高速度".$iNodeSpeed."M/S。
|
||||
覆盖".$sNodeZone."等多个区域。";
|
||||
|
||||
return $sContent;
|
||||
}
|
||||
|
||||
public static function nodeCount(): int
|
||||
{
|
||||
if (Pipeline::enabled()) {
|
||||
$store = Pipeline::store();
|
||||
return $store->locked(function () use ($store): int {
|
||||
$release = $store->current();
|
||||
if (!$release || ($release['validated'] ?? false) !== true
|
||||
|| ($release['date'] ?? '') !== date('Y-m-d')
|
||||
|| time() - ($release['created_at'] ?? 0) > 86400) {
|
||||
throw new RuntimeException('no_today_published_release_for_article');
|
||||
}
|
||||
$count = $release['counts']['v2ray'] ?? null;
|
||||
if (!is_int($count) || $count < 1) {
|
||||
throw new RuntimeException('invalid_published_node_count');
|
||||
}
|
||||
return $count;
|
||||
}, false);
|
||||
}
|
||||
$pool = FreenodePool::whereDate('date', date('Y-m-d'))->first();
|
||||
$content = json_decode($pool->content ?? '[]', true);
|
||||
return count($content['v2ray'] ?? []);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -229,3 +229,11 @@ Nodehub仍运行`507cbf7`,已在今天00:15正常生成20261022四站10份文
|
||||
回退:先`systemctl disable --now gitea-archive-cache-cleaner.timer`,停止service,再按部署备份恢复/移除本次独立脚本和两个unit并`systemctl daemon-reload`;无需回退免费节点业务代码。已删除缓存可按需重新生成。部署前检查生产HEAD、并行状态及旧文件,保留安装前状态和验收记录到服务器私有备份目录;本地5项测试覆盖过期/容量淘汰、打开文件/新文件/未知文件保护、符号链接、预览与重复执行。
|
||||
|
||||
2026-10-22部署验收:功能提交`48dc3ba6529226fae866d440625080632c1d88a0`已推送并部署;生产5项测试通过,systemd unit校验通过。timer已enabled/active,13:04:53首轮实际定时触发成功(退出0),清理53份过期缓存、共1,000,799,388字节,缓存由约956MiB降为0;复跑预览无额外候选。根盘可用3,323,936,768字节,Gitea仍active;当前订阅manifest逐字节不变,原并行Git状态保持。安装前状态、Git增量、预览与验收回执保存在`/var/backups/master01-gitea-cache-cleaner-20261022/`。已完成服务器侧验收,未做线上页面验收;尚不将一次成功视为长期磁盘容量保障。
|
||||
|
||||
### V2文章节点数量仍读旧池的问题
|
||||
|
||||
2026-10-22用户指出cfn首页“本次更新共0个可用节点”。服务器侧HTTP读取确认首页19/20/21日三篇均显示0,cfn数据库对应slug为`fn20261019`(id356)、`fn20261020`(id358)、`fn20261021`(id360),22日文章尚不存在。master01旧`freenode_pool`最新记录为18日;V2 prepare已经不再写该表,但`CountrySpeedService::fn_b()`仍按今天日期读旧池,空值经count变0,`?? rand()`不可能生效。这是重构遗漏的文章统计调用方,与订阅文件为空无关。
|
||||
|
||||
修正`CountrySpeedService::nodeCount()`:V2从当天current已验证批次的v2ray统计取值,不取pending、不回退旧池,不存在当日有效发布或数量无效则抛异常阻止生成0节点文章。legacy沿用原池逻辑;其他随机文案保持原样,本次未实现节点联网可用性/测速。测试覆盖published优先、pending拒绝、过期日期和零值拒绝;整套23项53断言通过。
|
||||
|
||||
现存cfn文案仅计划按对应日期已发布产物修正19/20/21日三个0计数,备份正文并事务更新`sTitleSub`/`sContent`内的数字,不重发文章、不改订阅/图片/点赞/标签、不触发Telegram或IndexNow;不把今天2592条套到历史日期。部署和实际修正结果待验收。
|
||||
|
||||
54
tests/Unit/Freenode/ArticleCountTest.php
Normal file
54
tests/Unit/Freenode/ArticleCountTest.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace Tests\Unit\Freenode;
|
||||
|
||||
use App\Services\CountrySpeedService;
|
||||
use Illuminate\Config\Repository;
|
||||
use Illuminate\Foundation\Application;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class ArticleCountTest extends TestCase
|
||||
{
|
||||
private string $dir;
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->dir = sys_get_temp_dir().'/article-count-'.bin2hex(random_bytes(6));
|
||||
mkdir($this->dir.'/app/freenode-v2', 0700, true);
|
||||
$app = new Application(dirname(__DIR__, 3));
|
||||
$app->useStoragePath($this->dir);
|
||||
$app->instance('config', new Repository(['freenode' => ['engine' => 'v2']]));
|
||||
}
|
||||
protected function tearDown(): void
|
||||
{
|
||||
foreach (glob($this->dir.'/app/freenode-v2/*') as $p) unlink($p);
|
||||
rmdir($this->dir.'/app/freenode-v2'); rmdir($this->dir.'/app'); rmdir($this->dir);
|
||||
}
|
||||
private function write(array $override = [], string $name = 'current'): void
|
||||
{
|
||||
$m = array_replace(['id'=>'published', 'validated'=>true, 'date'=>date('Y-m-d'),
|
||||
'created_at'=>time(), 'counts'=>['v2ray'=>2592]], $override);
|
||||
file_put_contents($this->dir.'/app/freenode-v2/'.$name.'.json', json_encode($m));
|
||||
}
|
||||
public function testV2ReadsPublishedCountWithoutLegacyDatabase(): void
|
||||
{
|
||||
$this->write(); $this->write(['counts'=>['v2ray'=>9999]], 'pending');
|
||||
self::assertSame(2592, CountrySpeedService::nodeCount());
|
||||
}
|
||||
public function testPendingAloneCannotProduceAnArticleCount(): void
|
||||
{
|
||||
$this->write([], 'pending');
|
||||
$this->expectExceptionMessage('no_today_published_release_for_article');
|
||||
CountrySpeedService::nodeCount();
|
||||
}
|
||||
public function testPreviousDayIsRejectedInsteadOfPublishingZero(): void
|
||||
{
|
||||
$this->write(['date'=>date('Y-m-d', time()-86400)]);
|
||||
$this->expectExceptionMessage('no_today_published_release_for_article');
|
||||
CountrySpeedService::nodeCount();
|
||||
}
|
||||
public function testZeroCountIsRejected(): void
|
||||
{
|
||||
$this->write(['counts'=>['v2ray'=>0]]);
|
||||
$this->expectExceptionMessage('invalid_published_node_count');
|
||||
CountrySpeedService::nodeCount();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user