Extract connection connect attempt

master
dev 5 months ago
parent 1aa9c4dd30
commit ed888e9f2d

@ -21,6 +21,7 @@ Estado al cierre:
- `arts/sess/engine-session.ts` delega la resolucion de revoke local/global/degradado en `session-revoke.ts`.
- `arts/conn/connection.ts` delega la programacion de reconnect y exhaustion en `connection-reconnect-runtime.ts`.
- `arts/conn/connection.ts` delega decode/routing de frames entrantes en `connection-message-router.ts`.
- `arts/conn/connection.ts` delega el intento open/auth/flush/join en `connection-connect.ts`.
- `arts/timr/engine-timers.ts` delega fan-out de listeners y diagnostico de listeners en `timer-events.ts`.
- Integracion total ampliada: `Auth.signOut()` valida anonimizacion, invalidacion de `Permissions` y evento `Cache.invalidate`.
- Tanda focalizada verde: `npx vitest run src/arts/conn src/libs/cach src/arts/cach src/svrs/cach src/arts/auth src/svrs/auth src/libs/auth src/arts/aapp/test/ecosystem.integration.test.ts` -> 19 archivos, 82 tests.

@ -0,0 +1,78 @@
import {
CONNECTION_CLOSE_REASON_AUTH_FAILED,
CONNECTION_CONNECT_REASON_AUTH_FAILED,
CONNECTION_CONNECT_REASON_TRANSPORT_ERROR,
CONNECTION_DIAGNOSTIC_EVENTS,
CONNECTION_STATE_CONNECTING,
CONNECTION_STATE_FAILED,
CONNECTION_STATE_RECONNECTING,
TIMER_KEY_RECONNECT
} from './consts.ts';
import { emitConnectionDiagnostic, type ConnectionDiagnostics } from './diagnostics.ts';
import type { ConnectionRequestRuntime } from './connection-requests.ts';
import type { ConnectionStateTracker } from './connection-state.ts';
import type { ConnectionTimerControls } from './connection-timers.ts';
import type { ConnectionSender } from './sender.ts';
import type { ConnectionConnectResult, ConnectionTransport } from './types.ts';
export interface RunConnectionConnectInput {
readonly reconnect: boolean;
readonly timers: ConnectionTimerControls;
resolveTransport(): ConnectionTransport;
setTransport(transport: ConnectionTransport): void;
attachTransport(transport: ConnectionTransport): void;
detachTransport(): void;
markOpen(): void;
markClosedFailed(error: unknown): void;
joinConfiguredChannels(reconnect: boolean): Promise<void>;
readonly state: ConnectionStateTracker;
readonly requests: ConnectionRequestRuntime;
readonly sender: ConnectionSender;
readonly diagnostics: ConnectionDiagnostics;
}
export async function runConnectionConnect(
input: RunConnectionConnectInput
): Promise<ConnectionConnectResult> {
input.timers.cancel(TIMER_KEY_RECONNECT);
const nextTransport = input.resolveTransport();
input.setTransport(nextTransport);
input.attachTransport(nextTransport);
input.state.transition(input.reconnect ? CONNECTION_STATE_RECONNECTING : CONNECTION_STATE_CONNECTING);
try {
await nextTransport.open();
input.markOpen();
if (input.requests.hasAuthProvider()) {
const auth = await input.requests.runAuth();
if (!auth.ok) {
const authError = auth.error ?? auth.reason;
input.state.setError(authError);
emitConnectionDiagnostic(input.diagnostics, CONNECTION_DIAGNOSTIC_EVENTS.AUTH_FAILED, auth);
input.detachTransport();
nextTransport.close(undefined, CONNECTION_CLOSE_REASON_AUTH_FAILED);
input.markClosedFailed(authError);
return {
ok: false,
state: input.state.state,
reason: CONNECTION_CONNECT_REASON_AUTH_FAILED,
error: authError
};
}
}
await input.sender.flushBuffer();
await input.joinConfiguredChannels(input.reconnect);
return { ok: true, state: input.state.state };
} catch (err) {
input.state.setError(err);
emitConnectionDiagnostic(input.diagnostics, CONNECTION_DIAGNOSTIC_EVENTS.CONNECT_FAILED, {
error: err
});
input.state.transition(CONNECTION_STATE_FAILED, err);
return {
ok: false,
state: input.state.state,
reason: CONNECTION_CONNECT_REASON_TRANSPORT_ERROR,
error: err
};
}
}

@ -2,6 +2,7 @@ import type { TimerScheduler } from '$timr';
import { createConnectionAckRegistry } from './acks.ts';
import { wireBrowserReconnect } from './browser-reconnect.ts';
import { createConnectionChannelRegistry } from './channel-registry.ts';
import { runConnectionConnect } from './connection-connect.ts';
import { createConnectionEventBus } from './connection-events.ts';
import { routeConnectionMessage } from './connection-message-router.ts';
import { scheduleConnectionReconnect } from './connection-reconnect-runtime.ts';
@ -12,16 +13,12 @@ import {
CONNECTION_ACK_REASON_CLOSED,
CONNECTION_CLOSE_REASON_DISCONNECT,
CONNECTION_CLOSE_REASON_DISPOSE,
CONNECTION_CLOSE_REASON_AUTH_FAILED,
CONNECTION_CLOSE_REASON_RECONNECT,
CONNECTION_CLOSE_REASON_SESSION_EXPIRED,
CONNECTION_CONNECT_REASON_AUTH_FAILED,
CONNECTION_CONNECT_REASON_DISPOSED,
CONNECTION_CONNECT_REASON_TRANSPORT_ERROR,
CONNECTION_DIAGNOSTIC_EVENTS,
CONNECTION_STATE_CLOSED,
CONNECTION_STATE_CLOSING,
CONNECTION_STATE_CONNECTING,
CONNECTION_STATE_FAILED,
CONNECTION_STATE_OPEN,
CONNECTION_STATE_RECONNECTING,
@ -232,46 +229,26 @@ export function createConnection<TChannels extends ConnectionChannelMap = Connec
connectPromise = (async () => {
intentionalClose = false;
timers.cancel(TIMER_KEY_RECONNECT);
const nextTransport = resolveTransport();
transport = nextTransport;
attachTransport(nextTransport);
stateTracker.transition(reconnect ? CONNECTION_STATE_RECONNECTING : CONNECTION_STATE_CONNECTING);
try {
await nextTransport.open();
markOpen();
if (requests.hasAuthProvider()) {
const auth = await requests.runAuth();
if (!auth.ok) {
const authError = auth.error ?? auth.reason;
stateTracker.setError(authError);
emitConnectionDiagnostic(diagnostics, CONNECTION_DIAGNOSTIC_EVENTS.AUTH_FAILED, auth);
detachTransport();
transport?.close(undefined, CONNECTION_CLOSE_REASON_AUTH_FAILED);
markClosed(CONNECTION_STATE_FAILED, authError);
return {
ok: false,
state: stateTracker.state,
reason: CONNECTION_CONNECT_REASON_AUTH_FAILED,
error: authError
};
}
}
await sender.flushBuffer();
await joinConfiguredChannels(reconnect);
return { ok: true, state: stateTracker.state };
} catch (err) {
stateTracker.setError(err);
emitConnectionDiagnostic(diagnostics, CONNECTION_DIAGNOSTIC_EVENTS.CONNECT_FAILED, {
error: err
return await runConnectionConnect({
reconnect,
timers,
resolveTransport,
setTransport: (nextTransport) => {
transport = nextTransport;
},
attachTransport,
detachTransport,
markOpen,
markClosedFailed: (error) => {
markClosed(CONNECTION_STATE_FAILED, error);
},
joinConfiguredChannels,
state: stateTracker,
requests,
sender,
diagnostics
});
stateTracker.transition(CONNECTION_STATE_FAILED, err);
return {
ok: false,
state: stateTracker.state,
reason: CONNECTION_CONNECT_REASON_TRANSPORT_ERROR,
error: err
};
} finally {
connectPromise = null;
}

Loading…
Cancel
Save

Powered by TurnKey Linux.