# spiritlhls/speedtest.cn-cn-id architecture

> Architecture diagram of the GitHub repository spiritlhls/speedtest.cn-cn-id, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/spiritlhls/speedtest.cn-cn-id
- Repository: https://github.com/spiritlhls/speedtest.cn-cn-id

## Overview

1. **Repository role**
   - This repo is primarily a **data distribution and automation repository**, not a traditional application. Its main artifacts are CSV files containing updated speedtest node IDs for `speedtest.cn`.

2. **Primary outputs**
   - The top-level CSVs are the core deliverables:
     - `CN.csv`, `HK.csv`, `JP.csv`, `SG.csv`, `TW.csv`
     - `mobile.csv`, `telecom.csv`, `unicom.csv`
   - These likely represent regional and ISP-oriented node lists used by the accompanying测速 script.

3. **Data domain**
   - The README makes clear the dataset is about **speedtest server IDs and endpoints** from `speedtest.cn`.
   - It emphasizes coverage of:
     - mainland China regions/operators
     - Hong Kong, Taiwan, Japan, Singapore
   - The repo is curated to support automated selection of low-latency nodes for testing.

4. **Update model**
   - The data is **refreshed daily**.
   - The README says the node collection is produced by a **closed-source crawler** and then automatically pushed here.
   - So the public repository is the publishing layer; the crawler itself is outside this tree.

5. **Automation boundary**
   - The `.github/workflows/` directory is the main operational subsystem in this repo.
   - Workflows present:
     - `main.yml`
     - `daily-update-private.yml`
     - `sync-to-public.yml`
   - These likely orchestrate scrape/update/sync activities, with at least one private source repository in the loop.

6. **Private-to-public sync flow**
   - The naming strongly suggests a two-stage pipeline:
     - a **private repo/workflow** updates the CSV data
     - a **sync workflow** mirrors selected results into this public repo
   - This is the main trust boundary: raw collection and possibly more complete internal data stay private, while a subset is published here.

7. **Consumer-facing flow**
   - End users do not interact with an API or service in this repo.
   - They consume the CSVs directly or via the referenced shell script URLs in the README, which use the published data as input for automated server selection.

8. **Operational dependency**
   - GitHub Actions is the only visible runtime/infrastructure component in the repo.
   - There is no application server, database, or containerized service defined here.
   - The architecture is therefore a **scheduled CI/CD-style data pipeline** rather than a deployable app.

9. **Region/ISP partitioning**
   - The CSV naming implies the dataset is partitioned by two axes:
     - **geography**: CN/HK/JP/SG/TW
     - **carrier type**: mobile/telecom/unicom
   - That partitioning matters architecturally because downstream scripts can choose between broad regional lists or operator-specific lists.

10. **Public data product**
   - The repo’s published state is effectively a **versioned snapshot of speedtest node metadata**.
   - The README’s “data update time” and server count indicate the CSVs are meant to be the authoritative, human-visible output of the pipeline.

11. **What is not in this repo**
   - There is no visible crawler code, parser logic, scheduler logic beyond workflow definitions, or business application layer.
   - For an architecture diagram, the important omission is that the **data acquisition engine is external/private**, while this repo is the distribution endpoint.

12. **Best diagram framing**
   - A clear diagram would show:
     - `speedtest.cn` as the upstream data source
     - a private crawler/collector as the ingestion layer
     - GitHub Actions as the automation/sync layer
     - this repo’s CSV files as the public dataset layer
     - shell-based consumer scripts as downstream consumers

Main entry points: [`.github/workflows/daily-update-private.yml`](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/.github/workflows/daily-update-private.yml) (Daily update), [`.github/workflows/sync-to-public.yml`](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/.github/workflows/sync-to-public.yml) (Sync public), [`.github/workflows/main.yml`](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/.github/workflows/main.yml) (Main flow), [`README.md`](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/README.md) (README)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_upstream["Upstream source"]
  node_speedtest_cn(("speedtest.cn<br/>external source"))
  node_private_crawler["Private crawler<br/>closed collector"]
end

subgraph group_automation["Automation"]
  node_actions["GitHub Actions<br/>ci runtime"]
  node_main_workflow["Main flow<br/>workflow<br/>[main.yml]"]
  node_daily_update["Daily update<br/>workflow"]
  node_sync_public["Sync public<br/>workflow<br/>[sync-to-public.yml]"]
end

subgraph group_published["Public dataset"]
  node_dataset_snapshot[("CSV snapshot<br/>published dataset")]
  node_region_csvs["Regional CSVs<br/>region partition"]
  node_isp_csvs["ISP CSVs<br/>carrier partition"]
  node_cn_csv["CN.csv<br/>region file<br/>[CN.csv]"]
  node_hk_csv["HK.csv<br/>region file<br/>[HK.csv]"]
  node_jp_csv["JP.csv<br/>region file<br/>[JP.csv]"]
  node_sg_csv["SG.csv<br/>region file<br/>[SG.csv]"]
  node_tw_csv["TW.csv<br/>region file<br/>[TW.csv]"]
  node_mobile_csv["mobile.csv<br/>carrier file<br/>[mobile.csv]"]
  node_telecom_csv["telecom.csv<br/>carrier file<br/>[telecom.csv]"]
  node_unicom_csv["unicom.csv<br/>carrier file<br/>[unicom.csv]"]
end

subgraph group_consumers["Consumers"]
  node_readme["README<br/>docs<br/>[README.md]"]
  node_shell_users["Shell users<br/>downstream consumer"]
end

node_speedtest_cn -->|"serve metadata"| node_private_crawler
node_private_crawler -->|"prepare update"| node_daily_update
node_daily_update -->|"run on CI"| node_actions
node_actions -->|"trigger sync"| node_sync_public
node_sync_public -->|"publish"| node_dataset_snapshot
node_dataset_snapshot -->|"split by region"| node_region_csvs
node_dataset_snapshot -->|"split by carrier"| node_isp_csvs
node_region_csvs -->|"contains"| node_cn_csv
node_region_csvs -->|"contains"| node_hk_csv
node_region_csvs -->|"contains"| node_jp_csv
node_region_csvs -->|"contains"| node_sg_csv
node_region_csvs -->|"contains"| node_tw_csv
node_isp_csvs -->|"contains"| node_mobile_csv
node_isp_csvs -->|"contains"| node_telecom_csv
node_isp_csvs -->|"contains"| node_unicom_csv
node_readme -->|"documented for"| node_shell_users
node_shell_users -->|"read"| node_region_csvs
node_shell_users -->|"read"| node_isp_csvs
node_main_workflow -->|"orchestrates"| node_daily_update
node_main_workflow -->|"orchestrates"| node_sync_public

click node_main_workflow "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/.github/workflows/main.yml"
click node_daily_update "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/.github/workflows/daily-update-private.yml"
click node_sync_public "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/.github/workflows/sync-to-public.yml"
click node_cn_csv "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/CN.csv"
click node_hk_csv "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/HK.csv"
click node_jp_csv "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/JP.csv"
click node_sg_csv "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/SG.csv"
click node_tw_csv "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/TW.csv"
click node_mobile_csv "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/mobile.csv"
click node_telecom_csv "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/telecom.csv"
click node_unicom_csv "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/unicom.csv"
click node_readme "https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/README.md"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_speedtest_cn,node_private_crawler toneBlue
class node_actions,node_main_workflow,node_daily_update,node_sync_public toneAmber
class node_dataset_snapshot,node_region_csvs,node_isp_csvs,node_cn_csv,node_hk_csv,node_jp_csv,node_sg_csv,node_tw_csv,node_mobile_csv,node_telecom_csv,node_unicom_csv toneMint
class node_readme,node_shell_users toneRose
```

## Components

### Upstream source

External speedtest.cn server metadata collected outside this public repo.

- **speedtest.cn**: external source · Upstream source of server IDs and endpoints.
- **Private crawler**: closed collector · Private collection layer that scrapes and prepares node data before publishing.

### Automation

GitHub Actions workflows that refresh and publish the dataset.

- **GitHub Actions**: ci runtime · Repository automation runtime used to update and sync data.
- [Main flow](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/.github/workflows/main.yml): workflow · Primary workflow entrypoint for repository automation. · `.github/workflows/main.yml`
- [Daily update](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/.github/workflows/daily-update-private.yml): workflow · Scheduled private-source refresh workflow. · `.github/workflows/daily-update-private.yml`
- [Sync public](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/.github/workflows/sync-to-public.yml): workflow · Mirrors selected results into this public repository. · `.github/workflows/sync-to-public.yml`

### Public dataset

Versioned CSV outputs committed to this repository.

- **CSV snapshot**: published dataset · Versioned public snapshot of speedtest node metadata.
- **Regional CSVs**: region partition · Country/region partitions: CN, HK, JP, SG, and TW.
- **ISP CSVs**: carrier partition · Carrier partitions: mobile, telecom, and unicom.
- [CN.csv](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/CN.csv): region file · Mainland China node list. · `CN.csv`
- [HK.csv](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/HK.csv): region file · Hong Kong node list. · `HK.csv`
- [JP.csv](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/JP.csv): region file · Japan node list. · `JP.csv`
- [SG.csv](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/SG.csv): region file · Singapore node list. · `SG.csv`
- [TW.csv](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/TW.csv): region file · Taiwan node list. · `TW.csv`
- [mobile.csv](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/mobile.csv): carrier file · Mobile operator node list. · `mobile.csv`
- [telecom.csv](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/telecom.csv): carrier file · Telecom operator node list. · `telecom.csv`
- [unicom.csv](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/unicom.csv): carrier file · Unicom operator node list. · `unicom.csv`

### Consumers

Human and shell-script users that read the published CSVs.

- [README](https://github.com/spiritlhls/speedtest.cn-cn-id/blob/main/README.md): docs · Explains the dataset, refresh cadence, and usage. · `README.md`
- **Shell users**: downstream consumer · Scripts and users that consume the CSVs for node selection.

## Connections

- speedtest.cn → Private crawler: serve metadata · Upstream server listings are collected by the private crawler.
- Private crawler → Daily update: prepare update · Collected data is fed into the scheduled refresh workflow.
- Daily update → GitHub Actions: run on CI · Workflow executes in GitHub Actions.
- GitHub Actions → Sync public: trigger sync · Automation publishes selected results to the public repo.
- Sync public → CSV snapshot: publish · Sync workflow updates the public CSV snapshot.
- CSV snapshot → Regional CSVs: split by region · Public snapshot is partitioned into regional lists.
- CSV snapshot → ISP CSVs: split by carrier · Public snapshot is partitioned into carrier-specific lists.
- Regional CSVs → CN.csv: contains · Regional dataset includes mainland China nodes.
- Regional CSVs → HK.csv: contains · Regional dataset includes Hong Kong nodes.
- Regional CSVs → JP.csv: contains · Regional dataset includes Japan nodes.
- Regional CSVs → SG.csv: contains · Regional dataset includes Singapore nodes.
- Regional CSVs → TW.csv: contains · Regional dataset includes Taiwan nodes.
- ISP CSVs → mobile.csv: contains · Carrier dataset includes mobile nodes.
- ISP CSVs → telecom.csv: contains · Carrier dataset includes telecom nodes.
- ISP CSVs → unicom.csv: contains · Carrier dataset includes unicom nodes.
- README → Shell users: documented for · README explains how consumers use the published CSVs.
- Shell users → Regional CSVs: read · Consumers choose regional lists for testing.
- Shell users → ISP CSVs: read · Consumers choose carrier lists for testing.
- Main flow → Daily update: orchestrates · Main workflow coordinates the update path.
- Main flow → Sync public: orchestrates · Main workflow coordinates public synchronization.
