Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cfc4cf378f | |||
| a09e69a28b | |||
| 82dd19e274 | |||
| c1d8afdbf7 | |||
| 9b7426f1e6 | |||
| 3c9c865841 |
19
changelog.md
19
changelog.md
@@ -1,5 +1,24 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-02-26 - 9.1.5 - fix(remoteingress)
|
||||
Reconcile tunnel manager edge statuses with authoritative Rust hub periodically; update active tunnel counts and heartbeats, add missed edges, remove stale entries, and clear reconcile interval on stop
|
||||
|
||||
- Add reconcile() to sync TS-side edgeStatuses with hub.getStatus and overwrite activeTunnels with the authoritative activeStreams.
|
||||
- Start a periodic reconcile (setInterval every 15s) and store the interval handle on the tunnel manager.
|
||||
- Clear the reconcile interval in stop() to avoid background timers; remove edgeStatuses entries that are no longer connected in Rust.
|
||||
- Bump dependency @serve.zone/remoteingress from ^4.0.0 to ^4.0.1.
|
||||
|
||||
## 2026-02-25 - 9.1.4 - fix(deps)
|
||||
bump @push.rocks/smartproxy to ^25.8.1
|
||||
|
||||
- Updated package.json dependency @push.rocks/smartproxy from ^25.8.0 to ^25.8.1
|
||||
|
||||
## 2026-02-24 - 9.1.3 - fix(deps)
|
||||
bump @api.global/typedserver to ^8.4.0 and @push.rocks/smartproxy to ^25.8.0
|
||||
|
||||
- Updated @api.global/typedserver from ^8.3.1 to ^8.4.0
|
||||
- Updated @push.rocks/smartproxy from ^25.7.9 to ^25.8.0
|
||||
|
||||
## 2026-02-24 - 9.1.2 - fix(deps)
|
||||
bump dependency versions for build and runtime packages
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@serve.zone/dcrouter",
|
||||
"private": false,
|
||||
"version": "9.1.2",
|
||||
"version": "9.1.5",
|
||||
"description": "A multifaceted routing service handling mail and SMS delivery functions.",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
@@ -29,7 +29,7 @@
|
||||
"dependencies": {
|
||||
"@api.global/typedrequest": "^3.2.6",
|
||||
"@api.global/typedrequest-interfaces": "^3.0.19",
|
||||
"@api.global/typedserver": "^8.3.1",
|
||||
"@api.global/typedserver": "^8.4.0",
|
||||
"@api.global/typedsocket": "^4.1.0",
|
||||
"@apiclient.xyz/cloudflare": "^7.1.0",
|
||||
"@design.estate/dees-catalog": "^3.43.3",
|
||||
@@ -49,7 +49,7 @@
|
||||
"@push.rocks/smartnetwork": "^4.4.0",
|
||||
"@push.rocks/smartpath": "^6.0.0",
|
||||
"@push.rocks/smartpromise": "^4.2.3",
|
||||
"@push.rocks/smartproxy": "^25.7.9",
|
||||
"@push.rocks/smartproxy": "^25.8.1",
|
||||
"@push.rocks/smartradius": "^1.1.1",
|
||||
"@push.rocks/smartrequest": "^5.0.1",
|
||||
"@push.rocks/smartrx": "^3.0.10",
|
||||
@@ -57,7 +57,7 @@
|
||||
"@push.rocks/smartunique": "^3.0.9",
|
||||
"@serve.zone/catalog": "^2.5.0",
|
||||
"@serve.zone/interfaces": "^5.3.0",
|
||||
"@serve.zone/remoteingress": "^4.0.0",
|
||||
"@serve.zone/remoteingress": "^4.0.1",
|
||||
"@tsclass/tsclass": "^9.3.0",
|
||||
"lru-cache": "^11.2.6",
|
||||
"uuid": "^13.0.0"
|
||||
|
||||
65
pnpm-lock.yaml
generated
65
pnpm-lock.yaml
generated
@@ -15,8 +15,8 @@ importers:
|
||||
specifier: ^3.0.19
|
||||
version: 3.0.19
|
||||
'@api.global/typedserver':
|
||||
specifier: ^8.3.1
|
||||
version: 8.3.1(@tiptap/pm@2.27.2)
|
||||
specifier: ^8.4.0
|
||||
version: 8.4.0(@tiptap/pm@2.27.2)
|
||||
'@api.global/typedsocket':
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0(@push.rocks/smartserve@2.0.1)
|
||||
@@ -75,8 +75,8 @@ importers:
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3
|
||||
'@push.rocks/smartproxy':
|
||||
specifier: ^25.7.9
|
||||
version: 25.7.9
|
||||
specifier: ^25.8.1
|
||||
version: 25.8.1
|
||||
'@push.rocks/smartradius':
|
||||
specifier: ^1.1.1
|
||||
version: 1.1.1
|
||||
@@ -99,8 +99,8 @@ importers:
|
||||
specifier: ^5.3.0
|
||||
version: 5.3.0
|
||||
'@serve.zone/remoteingress':
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1
|
||||
'@tsclass/tsclass':
|
||||
specifier: ^9.3.0
|
||||
version: 9.3.0
|
||||
@@ -144,8 +144,8 @@ packages:
|
||||
'@api.global/typedserver@3.0.80':
|
||||
resolution: {integrity: sha512-dcp0oXsjBL+XdFg1wUUP08uJQid5bQ0Yv3V3Y3lnI2QCbat0FU+Tsb0TZRnZ4+P150Vj/ITBqJUgDzFsF34grA==}
|
||||
|
||||
'@api.global/typedserver@8.3.1':
|
||||
resolution: {integrity: sha512-rkUMAGB804blZ/315mTKD0ZIvxmbyXVepuuL4qwUWxY8+QtZdBfsA2fLGvaiTHEqA7ahwgp/NojpUpjW+SZHyA==}
|
||||
'@api.global/typedserver@8.4.0':
|
||||
resolution: {integrity: sha512-qOa5jUwiuHEoY1ZuLZiuU1unPl5JNd99Vv+hNAwgEIgAZd4TTy/mjdTp7lyviBzkGf2pROeCmAbDJJF8YQFCSA==}
|
||||
|
||||
'@api.global/typedsocket@3.1.1':
|
||||
resolution: {integrity: sha512-Wkz3NlhmfdZMKqXXI2c2dMtGGmSmhdOegZiziL+9b2mqPYdc7Gd8AZRdEOKvbSoIvc9G22/5BEadIWHrfq66TA==}
|
||||
@@ -1036,8 +1036,8 @@ packages:
|
||||
'@push.rocks/smartpromise@4.2.3':
|
||||
resolution: {integrity: sha512-Ycg/TJR+tMt+S3wSFurOpEoW6nXv12QBtKXgBcjMZ4RsdO28geN46U09osPn9N9WuwQy1PkmTV5J/V4F9U8qEw==}
|
||||
|
||||
'@push.rocks/smartproxy@25.7.9':
|
||||
resolution: {integrity: sha512-5esFvD72TEyveaEQbDYRgD7C5hDfWMSBvurNx3KPi02CBKG1gnhx/WWT7RHDS3KRF5fEQh9YxvI9aMkOwjc7sQ==}
|
||||
'@push.rocks/smartproxy@25.8.1':
|
||||
resolution: {integrity: sha512-f192aGYWXnF4pJNqBShy+pL6GPxFUECBWuymay5M5qD41uKS76GIieAegEu9/G9XhtFfricvu28s1JeXzU9fLA==}
|
||||
|
||||
'@push.rocks/smartpuppeteer@2.0.5':
|
||||
resolution: {integrity: sha512-yK/qSeWVHIGWRp3c8S5tfdGP6WCKllZC4DR8d8CQlEjszOSBmHtlTdyyqOMBZ/BA4kd+eU5f3A1r4K2tGYty1g==}
|
||||
@@ -1060,6 +1060,9 @@ packages:
|
||||
'@push.rocks/smartrust@1.2.1':
|
||||
resolution: {integrity: sha512-ANwXXibUwoHNWF1hhXhXVVrfzYlhgHYRa2205Jkd/s/wXzcWHftYZthilJj+52B7nkzSB76umfxKfK5eBYY2Ug==}
|
||||
|
||||
'@push.rocks/smartrust@1.3.1':
|
||||
resolution: {integrity: sha512-3ApbgF6yGeE2TRQxBY9Y48H1JlpcRheIp7QDBLSSfk80Uoe6fjdgBAfNz3Ir8hW3RZ3b7hA3sm1ZshCok58SEA==}
|
||||
|
||||
'@push.rocks/smartrx@3.0.10':
|
||||
resolution: {integrity: sha512-USjIYcsSfzn14cwOsxgq/bBmWDTTzy3ouWAnW5NdMyRRzEbmeNrvmy6TRqNeDlJ2PsYNTt1rr/zGUqvIy72ITg==}
|
||||
|
||||
@@ -1342,8 +1345,8 @@ packages:
|
||||
'@serve.zone/interfaces@5.3.0':
|
||||
resolution: {integrity: sha512-venO7wtDR9ixzD9NhdERBGjNKbFA5LL0yHw4eqGh0UpmvtXVc3SFG0uuHDilOKMZqZ8bttV88qVsFy1aSTJrtA==}
|
||||
|
||||
'@serve.zone/remoteingress@4.0.0':
|
||||
resolution: {integrity: sha512-kcC9pnQdS5Mw0ypmwT3GIYwrjVQJOjWw5TJ+j46t6Y98S4Mb7wEAAPsU+YRXozpkqUxWUDBeDK1fQHLvoF9PmQ==}
|
||||
'@serve.zone/remoteingress@4.0.1':
|
||||
resolution: {integrity: sha512-vl3nSGETsIR/BE1T2lvVGD1s4AMqh1CBAP7SNUnshXzYFzyFD2Fs1VmOEXP5V7grglawIuewhu+Th7eomC6zIA==}
|
||||
|
||||
'@sindresorhus/is@5.6.0':
|
||||
resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==}
|
||||
@@ -2009,6 +2012,10 @@ packages:
|
||||
resolution: {integrity: sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
balanced-match@4.0.4:
|
||||
resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
|
||||
bare-events@2.8.2:
|
||||
resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==}
|
||||
peerDependencies:
|
||||
@@ -2075,6 +2082,10 @@ packages:
|
||||
resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
brace-expansion@5.0.3:
|
||||
resolution: {integrity: sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
|
||||
broadcast-channel@7.3.0:
|
||||
resolution: {integrity: sha512-UHPhLBQKfQ8OmMFMpmPfO5dRakyA1vsfiDGWTYNvChYol65tbuhivPEGgZZiuetorvExdvxaWiBy/ym1Ty08yA==}
|
||||
|
||||
@@ -3234,6 +3245,10 @@ packages:
|
||||
resolution: {integrity: sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
minimatch@10.2.2:
|
||||
resolution: {integrity: sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
|
||||
minimatch@3.1.3:
|
||||
resolution: {integrity: sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==}
|
||||
|
||||
@@ -4337,7 +4352,7 @@ snapshots:
|
||||
- utf-8-validate
|
||||
- vue
|
||||
|
||||
'@api.global/typedserver@8.3.1(@tiptap/pm@2.27.2)':
|
||||
'@api.global/typedserver@8.4.0(@tiptap/pm@2.27.2)':
|
||||
dependencies:
|
||||
'@api.global/typedrequest': 3.2.6
|
||||
'@api.global/typedrequest-interfaces': 3.0.19
|
||||
@@ -5273,7 +5288,7 @@ snapshots:
|
||||
|
||||
'@git.zone/tswatch@3.2.0(@tiptap/pm@2.27.2)':
|
||||
dependencies:
|
||||
'@api.global/typedserver': 8.3.1(@tiptap/pm@2.27.2)
|
||||
'@api.global/typedserver': 8.4.0(@tiptap/pm@2.27.2)
|
||||
'@git.zone/tsbundle': 2.9.0
|
||||
'@git.zone/tsrun': 2.0.1
|
||||
'@push.rocks/early': 4.0.4
|
||||
@@ -6326,13 +6341,13 @@ snapshots:
|
||||
|
||||
'@push.rocks/smartpromise@4.2.3': {}
|
||||
|
||||
'@push.rocks/smartproxy@25.7.9':
|
||||
'@push.rocks/smartproxy@25.8.1':
|
||||
dependencies:
|
||||
'@push.rocks/smartcrypto': 2.0.4
|
||||
'@push.rocks/smartlog': 3.2.1
|
||||
'@push.rocks/smartrust': 1.2.1
|
||||
'@tsclass/tsclass': 9.3.0
|
||||
minimatch: 10.2.1
|
||||
minimatch: 10.2.2
|
||||
|
||||
'@push.rocks/smartpuppeteer@2.0.5(typescript@5.9.3)':
|
||||
dependencies:
|
||||
@@ -6389,6 +6404,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@push.rocks/smartpath': 6.0.0
|
||||
|
||||
'@push.rocks/smartrust@1.3.1':
|
||||
dependencies:
|
||||
'@push.rocks/smartpath': 6.0.0
|
||||
|
||||
'@push.rocks/smartrx@3.0.10':
|
||||
dependencies:
|
||||
'@push.rocks/smartpromise': 4.2.3
|
||||
@@ -6809,10 +6828,10 @@ snapshots:
|
||||
'@push.rocks/smartlog-interfaces': 3.0.2
|
||||
'@tsclass/tsclass': 9.3.0
|
||||
|
||||
'@serve.zone/remoteingress@4.0.0':
|
||||
'@serve.zone/remoteingress@4.0.1':
|
||||
dependencies:
|
||||
'@push.rocks/qenv': 6.1.3
|
||||
'@push.rocks/smartrust': 1.2.1
|
||||
'@push.rocks/smartrust': 1.3.1
|
||||
|
||||
'@sindresorhus/is@5.6.0': {}
|
||||
|
||||
@@ -7626,6 +7645,8 @@ snapshots:
|
||||
dependencies:
|
||||
jackspeak: 4.2.3
|
||||
|
||||
balanced-match@4.0.4: {}
|
||||
|
||||
bare-events@2.8.2: {}
|
||||
|
||||
bare-fs@4.5.3:
|
||||
@@ -7698,6 +7719,10 @@ snapshots:
|
||||
dependencies:
|
||||
balanced-match: 4.0.2
|
||||
|
||||
brace-expansion@5.0.3:
|
||||
dependencies:
|
||||
balanced-match: 4.0.4
|
||||
|
||||
broadcast-channel@7.3.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.6
|
||||
@@ -9142,6 +9167,10 @@ snapshots:
|
||||
dependencies:
|
||||
brace-expansion: 5.0.2
|
||||
|
||||
minimatch@10.2.2:
|
||||
dependencies:
|
||||
brace-expansion: 5.0.3
|
||||
|
||||
minimatch@3.1.3:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.12
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/dcrouter',
|
||||
version: '9.1.2',
|
||||
version: '9.1.5',
|
||||
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ export class TunnelManager {
|
||||
private manager: RemoteIngressManager;
|
||||
private config: ITunnelManagerConfig;
|
||||
private edgeStatuses: Map<string, IRemoteIngressStatus> = new Map();
|
||||
private reconcileInterval: ReturnType<typeof setInterval> | null = null;
|
||||
|
||||
constructor(manager: RemoteIngressManager, config: ITunnelManagerConfig = {}) {
|
||||
this.manager = manager;
|
||||
@@ -65,16 +66,62 @@ export class TunnelManager {
|
||||
|
||||
// Send allowed edges to the hub
|
||||
await this.syncAllowedEdges();
|
||||
|
||||
// Periodically reconcile with authoritative Rust hub status
|
||||
this.reconcileInterval = setInterval(() => {
|
||||
this.reconcile().catch(() => {});
|
||||
}, 15_000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the tunnel hub.
|
||||
*/
|
||||
public async stop(): Promise<void> {
|
||||
if (this.reconcileInterval) {
|
||||
clearInterval(this.reconcileInterval);
|
||||
this.reconcileInterval = null;
|
||||
}
|
||||
await this.hub.stop();
|
||||
this.edgeStatuses.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconcile TS-side edge statuses with the authoritative Rust hub status.
|
||||
* Overwrites event-derived activeTunnels with the real activeStreams count.
|
||||
*/
|
||||
private async reconcile(): Promise<void> {
|
||||
const hubStatus = await this.hub.getStatus();
|
||||
if (!hubStatus || !hubStatus.connectedEdges) return;
|
||||
|
||||
const rustEdgeIds = new Set<string>();
|
||||
|
||||
for (const rustEdge of hubStatus.connectedEdges) {
|
||||
rustEdgeIds.add(rustEdge.edgeId);
|
||||
const existing = this.edgeStatuses.get(rustEdge.edgeId);
|
||||
if (existing) {
|
||||
existing.activeTunnels = rustEdge.activeStreams;
|
||||
existing.lastHeartbeat = Date.now();
|
||||
} else {
|
||||
// Missed edgeConnected event — add entry
|
||||
this.edgeStatuses.set(rustEdge.edgeId, {
|
||||
edgeId: rustEdge.edgeId,
|
||||
connected: true,
|
||||
publicIp: null,
|
||||
activeTunnels: rustEdge.activeStreams,
|
||||
lastHeartbeat: Date.now(),
|
||||
connectedAt: rustEdge.connectedAt * 1000,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Remove entries for edges no longer connected in Rust (missed edgeDisconnected)
|
||||
for (const edgeId of this.edgeStatuses.keys()) {
|
||||
if (!rustEdgeIds.has(edgeId)) {
|
||||
this.edgeStatuses.delete(edgeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync allowed edges from the manager to the hub.
|
||||
* Call this after creating/deleting/updating edges.
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/dcrouter',
|
||||
version: '9.1.2',
|
||||
version: '9.1.5',
|
||||
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user