feat(SurgeMac): expose mihomoMerge / mihomoMergeName via URL query#588
Merged
xream merged 1 commit intoMay 15, 2026
Merged
Conversation
The producer (producers/surgemac.js) already supports a merge mode that emits N SOCKS5 listeners + one shared mihomo external process, avoiding the "one mihomo process per node" pattern. However the only way to enable it today is to write a per-proxy script operator that sets `_merge = true`. For users on networks where many subscription nodes are unreachable (e.g. CERNET / 校园网 to overseas VPS), the current default spawns dozens of idle-but-stuck mihomo subprocesses, each accumulating ~8s GFW-timeout outbound attempts that can cause system-wide slowdown. This patch wires two new URL query parameters into `produceOpts`: - `mihomoMerge=true|1` — enables the existing merge mode - `mihomoMergeName=<name>` — optional name for the merged entry Both only take effect when `target=SurgeMac` (i.e. when `useMihomoExternal` is already on). No behavior change for existing requests; default is unchanged.
There was a problem hiding this comment.
Pull request overview
Adds two new URL query parameters (mihomoMerge and mihomoMergeName) to the /download/... endpoints in download.js, plumbing them through produceOpts to the existing merge-mode branch in surgemac.js. The goal is to let users enable shared-mihomo-process output without writing a custom script operator.
Changes:
- Parse
mihomoMerge/mihomoMergeNamefromreq.queryin bothdownloadSubscriptionanddownloadCollection, gated ontarget=SurgeMac. - Pass them through as
merge/mergeNameinsideproduceOpts. - Emit an info log line when merge mode is enabled.
Comments suppressed due to low confidence (1)
backend/src/restful/download.js:445
- Same issue as in
downloadSubscription: whenmihomoMergeis not provided in the query string,req.query.mihomoMerge ?? ''yields'', which matches the['true', '1', '']list, so merge mode is silently enabled for everytarget=SurgeMaccollection download. This should only be enabled when the user explicitly opts in (e.g., value is'true'or'1').
const mihomoMerge =
useMihomoExternal &&
['true', '1', ''].includes(String(req.query.mihomoMerge ?? ''));
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // 等价于在脚本里对每个节点设置 _merge=true,避免每个节点 spawn 一个 mihomo 进程 | ||
| const mihomoMerge = | ||
| useMihomoExternal && | ||
| ['true', '1', ''].includes(String(req.query.mihomoMerge ?? '')); |
Member
|
Thank you for your PR. However, there are some issues with the code and it doesn't quite match the previous style. I will reimplement it based on your requirements and give you credit. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
producers/surgemac.jsalready implements a merge mode (surgemac.js#L119-L160) that emits:socks5,127.0.0.1:<port>Surge proxy entries (one per node), andexternal,exec=mihomo,args=-config <merged-config>entry with N inbound SOCKS5 listeners and N internalproxies[]This is exactly the right shape when a subscription contains many nodes whose protocol Surge does not natively support (e.g. VLESS-Reality with
xtls-rprx-vision) — Surge needs only one mihomo subprocess, regardless of node count.However, the only way to enable it today is to add a JS script operator that sets
_merge = trueon every proxy (documented as comment #24 inscripts/demo.js). Many users don't know this exists.Real-world impact observed
On a CERNET / 校园网 with native IPv6, where most overseas VPS IPs are reachable only intermittently:
*.inetsnode.de:<port>External Bypassrule → DIRECTdoh.pub) saturated the outbound SYN queue and Surge's flow-tracking pathConfirmed via
surge-cli --raw dump active+dump recent: every slow connection hadprocessPath=mihomoandrule=External Bypass. Killing all mihomo processes immediately restored normal performance.The merge mode would have eliminated this entirely (1 process instead of 53), but requires the user to either:
_mergefields after the producer runs (loses on next sync)What this PR does
Adds two URL query parameters that flow through to
produceOpts:mihomoMerge'true' | '1' | ''target=SurgeMac)mihomoMergeNamemihomo merged)The producer code already reads
opts.mergeandopts.mergeName, so this PR is purely plumbing.Diff scope
backend/src/restful/download.js— bothdownloadSubscriptionanddownloadCollection: parse query params + pass intoproduceOpts. Two log lines when enabled. ~38 added lines, no removals.mihomoMergeis absent — default unchanged.Usage
Tests / verification
node --check backend/src/restful/download.jspassesproduceOpts→ProxyUtils.produce(...)→surgemac.jsproduce(proxy, type, opts)→const merge = opts?.merge || proxy._merge→ existing merge branchtargetother thanSurgeMacshort-circuits tofalse, so this can't affect Surge / Clash / sing-box / Loon / etc. outputsFollow-ups (not in this PR)
mihomoMergeon the Artifact entity forcron-sync-artifacts.js, but that's a UI/data-model change and worth a separate discussion.scripts/demo.jscomment “发生错误,无法创建订阅” #24 mentioning the URL-param form — happy to add in this PR if preferred.