mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(portless): fall forward when branch route is occupied
This commit is contained in:
@@ -75,5 +75,5 @@ If uncertain, ask the developer before adding an entry.
|
|||||||
- **Context:** Starting `yarn start` in one 5chan worktree while another 5chan worktree was already serving through Portless
|
- **Context:** Starting `yarn start` in one 5chan worktree while another 5chan worktree was already serving through Portless
|
||||||
- **What was surprising:** Using the literal Portless app name `5chan` in every worktree makes the route itself collide, even when the backing ports are different, so the second process fails with `"5chan.localhost" is already registered`.
|
- **What was surprising:** Using the literal Portless app name `5chan` in every worktree makes the route itself collide, even when the backing ports are different, so the second process fails with `"5chan.localhost" is already registered`.
|
||||||
- **Impact:** Parallel 5chan branches can block each other even though Portless is meant to let them coexist safely.
|
- **Impact:** Parallel 5chan branches can block each other even though Portless is meant to let them coexist safely.
|
||||||
- **Mitigation:** Keep Portless startup behind `scripts/start-dev.js`, which now uses a branch-scoped `*.5chan.localhost:1355` route outside the canonical case and falls back to a branch-scoped route when the bare `5chan.localhost` name is already occupied.
|
- **Mitigation:** Keep Portless startup behind `scripts/start-dev.js`, which now uses a branch-scoped `*.5chan.localhost:1355` route outside the canonical case and automatically increments a `-2`, `-3`, ... suffix when that branch-scoped route is already occupied.
|
||||||
- **Status:** confirmed
|
- **Status:** confirmed
|
||||||
|
|||||||
+30
-5
@@ -36,7 +36,7 @@ function getCurrentBranch() {
|
|||||||
return branch || null;
|
return branch || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isCanonicalRouteBusy() {
|
function getActivePortlessRoutes() {
|
||||||
const result = spawnSync(portlessBin, ['list'], {
|
const result = spawnSync(portlessBin, ['list'], {
|
||||||
cwd: process.cwd(),
|
cwd: process.cwd(),
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
@@ -44,13 +44,19 @@ function isCanonicalRouteBusy() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result.status !== 0) {
|
if (result.status !== 0) {
|
||||||
return false;
|
return new Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.stdout.includes('http://5chan.localhost:1355');
|
const matches = result.stdout.match(/http:\/\/[a-z0-9.-]+\.localhost:1355/g) || [];
|
||||||
|
|
||||||
|
return new Set(matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPortlessAppName() {
|
function isRouteBusy(activeRoutes, appName) {
|
||||||
|
return activeRoutes.has(`http://${appName}.localhost:1355`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPreferredPortlessAppName(activeRoutes) {
|
||||||
const branch = getCurrentBranch();
|
const branch = getCurrentBranch();
|
||||||
const branchLabel = sanitizeLabel(branch || 'current');
|
const branchLabel = sanitizeLabel(branch || 'current');
|
||||||
|
|
||||||
@@ -58,13 +64,32 @@ function getPortlessAppName() {
|
|||||||
return `${branchLabel}.5chan`;
|
return `${branchLabel}.5chan`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCanonicalRouteBusy()) {
|
if (isRouteBusy(activeRoutes, '5chan')) {
|
||||||
return `${branchLabel}.5chan`;
|
return `${branchLabel}.5chan`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return '5chan';
|
return '5chan';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPortlessAppName() {
|
||||||
|
const activeRoutes = getActivePortlessRoutes();
|
||||||
|
const preferredAppName = getPreferredPortlessAppName(activeRoutes);
|
||||||
|
|
||||||
|
if (!isRouteBusy(activeRoutes, preferredAppName)) {
|
||||||
|
return preferredAppName;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let suffix = 2; suffix < 1000; suffix += 1) {
|
||||||
|
const candidate = `${preferredAppName}-${suffix}`;
|
||||||
|
|
||||||
|
if (!isRouteBusy(activeRoutes, candidate)) {
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${preferredAppName}-${Date.now()}`;
|
||||||
|
}
|
||||||
|
|
||||||
const command = usePortless && existsSync(portlessBin) ? portlessBin : viteBin;
|
const command = usePortless && existsSync(portlessBin) ? portlessBin : viteBin;
|
||||||
let args;
|
let args;
|
||||||
let publicUrl = null;
|
let publicUrl = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user