fix: ranking refresh deadlock, switch to direct HTTP, add CI pipeline
Some checks failed
CI / Lint (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Build (push) Has been cancelled

- Fix channel drain goroutine deadlock in handleRankingRefresh: replace
  'for { ... continue ... if nil break }' with 'for A != nil || B != nil'
  so the select never blocks on two nil channels
- Switch ScrapeRanking from urlClient (Browserless) to client (direct HTTP)
  since novelfire.net/ranking is fully server-rendered — no JS needed
- Add ranking unit tests (single page, multi-page, empty page, write round-trip)
- Add .gitea/workflows/ci.yaml: lint, test, build jobs with commented-out
  Docker image push step for when runner has Docker available
This commit is contained in:
Admin
2026-03-01 19:45:28 +05:00
parent afa457cedd
commit 26302058d0
4 changed files with 310 additions and 25 deletions

View File

@@ -455,35 +455,30 @@ func (s *Server) handleRankingRefresh(w http.ResponseWriter, r *http.Request) {
rankingCh, errCh := s.novel.ScrapeRanking(ctx, maxPages)
var rankingItems []writer.RankingItem
for {
for rankingCh != nil || errCh != nil {
select {
case meta, ok := <-rankingCh:
if !ok {
rankingCh = nil
continue
} else {
rankingItems = append(rankingItems, writer.RankingItem{
Rank: meta.Ranking,
Slug: meta.Slug,
Title: meta.Title,
Author: meta.Author,
Cover: meta.Cover,
Status: meta.Status,
Genres: meta.Genres,
SourceURL: meta.SourceURL,
})
}
rankingItems = append(rankingItems, writer.RankingItem{
Rank: meta.Ranking,
Slug: meta.Slug,
Title: meta.Title,
Author: meta.Author,
Cover: meta.Cover,
Status: meta.Status,
Genres: meta.Genres,
SourceURL: meta.SourceURL,
})
case err, ok := <-errCh:
if !ok {
errCh = nil
continue
}
if err != nil {
} else if err != nil {
s.log.Error("ranking scrape error", "err", err)
}
}
if rankingCh == nil && errCh == nil {
break
}
}
if len(rankingItems) > 0 {