import { NgZone } from '@angular/core'; import { ConfigService } from 'tabby-core'; import { SSHTabComponent } from 'tabby-ssh'; /** What the dot next to a session shows. */ export type PingState = 'good' | 'fair' | 'poor' | 'unknown' | 'unavailable'; /** * Round-trip latency of the live SSH sessions, measured on the sessions * themselves. * * There is nothing to read: neither Tabby nor russh keeps a round-trip time * anywhere (checked on the installed bundle — russh's only mention of * keepalives is the interval handed to `connect()`, which reports nothing * back). So the number has to be produced, and the choice of how says what the * dot actually means. * * A timed SFTP request on the session's own channel, rather than an ICMP ping * or a TCP connect to port 22: * * - it measures the *encrypted round trip of this session* — the delay that * is felt when typing — where ICMP measures the host and is commonly * filtered outright, which would show red on a perfectly good link; * - it opens nothing. A TCP probe would start, then abandon, a connection * before authentication on every tick: a trail in the server's auth log, * and a plausible way to get banned by one's own fail2ban; * - no external process, unlike `ping.exe`, once per session per tick. * * Two consequences to know about. The channel is shared with real SFTP work * (`SSHSession.openSFTP()` caches one channel per session), so a probe sent * during a large transfer queues behind its data and reads high — that is the * session genuinely being slow to answer, not a wrong measurement. And a * server with no SFTP subsystem cannot be measured at all: that session is * marked unavailable once and never probed again. */ export declare class SidebarPlusPingService { private config; private zone; private samples; /** Probes in flight, so a slow answer cannot pile up behind itself. */ private inFlight; /** Sessions whose server has no SFTP subsystem — asked once, never again. */ private unavailable; constructor(config: ConfigService, zone: NgZone); /** 0 disables the whole thing, which is the default — see the settings tab. */ get intervalMs(): number; /** * Called on the tree's existing 2s poll, once per live session: no timer of * its own, on purpose. The tunnels list is refreshed the same way, and a * second interval in the sidebar is a second thing to remember to stop. */ poll(tabs: SSHTabComponent[]): void; state(tab: SSHTabComponent): PingState; /** * The last measured round trip, or null when there is none — probing off, * first probe not back yet, or a server that opens no SFTP channel. * * The raw number rather than a sentence: the tooltip that shows it is a * compact `profil | 13 ms | 1m 47s`, so the wording belongs to the caller * and a placeholder here would have to be dropped by it anyway. */ latencyMs(tab: SSHTabComponent): number | null; /** * One round trip on the session's SFTP channel. * * `stat('.')` is used as a *ping*, not as an observation: nothing in the * answer is read, only the time it took to come back. That distinction * matters here, because `stat()` is banned everywhere else in this codebase * for observing an entry — it answers mode 0 and a 1970 date (piège #50) — * and this is not that. It is the smallest request the protocol has: one * packet out, one small packet back, no directory listing. */ private probe; }