Extract connection connect controller

master
dev 5 months ago
parent 1f0929230a
commit ea424b1b3b

@ -43,6 +43,7 @@ Estado al cierre:
- `arts/conn/connection.ts` delega el intento open/auth/flush/join en `connection-connect.ts`.
- `arts/conn/connection.ts` delega current transport, attach/detach y close en `connection-transport-runtime.ts`.
- `arts/conn/connection.ts` delega cierre intencional y close-event handling en `connection-close.ts`.
- `arts/conn/connection.ts` delega disposed/reuse/singleflight de connect en `connection-connect-controller.ts`.
- `arts/timr/engine-timers.ts` delega fan-out de listeners y diagnostico de listeners en `timer-events.ts`.
- `arts/timr/engine-timers.ts` delega la construccion de entradas internas en `timer-entry.ts`.
- `arts/timr/engine-timers.ts` delega cancelacion y seleccion por scope en `timer-cancel.ts`.

@ -0,0 +1,51 @@
import {
CONNECTION_CONNECT_REASON_DISPOSED,
CONNECTION_STATE_OPEN
} from './consts.ts';
import type { ConnectionConnectResult, ConnectionState } from './types.ts';
export interface ConnectionConnectController {
connect(reconnect: boolean): Promise<ConnectionConnectResult>;
}
export interface ConnectionConnectControllerOptions {
getState(): ConnectionState;
isDisposed(): boolean;
isConnected(): boolean;
beforeAttempt(): void;
runConnect(reconnect: boolean): Promise<ConnectionConnectResult>;
}
export function createConnectionConnectController(
options: ConnectionConnectControllerOptions
): ConnectionConnectController {
let connectPromise: Promise<ConnectionConnectResult> | null = null;
function connect(reconnect: boolean): Promise<ConnectionConnectResult> {
const state = options.getState();
if (options.isDisposed()) {
return Promise.resolve({
ok: false,
state,
reason: CONNECTION_CONNECT_REASON_DISPOSED
});
}
if (state === CONNECTION_STATE_OPEN && options.isConnected()) {
return Promise.resolve({ ok: true, state, reused: true });
}
if (connectPromise !== null) return connectPromise;
connectPromise = (async () => {
options.beforeAttempt();
try {
return await options.runConnect(reconnect);
} finally {
connectPromise = null;
}
})();
return connectPromise;
}
return { connect };
}

@ -7,6 +7,7 @@ import {
handleConnectionTransportClose,
type ConnectionCloseRuntime
} from './connection-close.ts';
import { createConnectionConnectController } from './connection-connect-controller.ts';
import { runConnectionConnect } from './connection-connect.ts';
import { createConnectionEventBus } from './connection-events.ts';
import { routeConnectionMessage } from './connection-message-router.ts';
@ -19,10 +20,8 @@ import {
CONNECTION_CLOSE_REASON_DISPOSE,
CONNECTION_CLOSE_REASON_RECONNECT,
CONNECTION_CLOSE_REASON_SESSION_EXPIRED,
CONNECTION_CONNECT_REASON_DISPOSED,
CONNECTION_DIAGNOSTIC_EVENTS,
CONNECTION_STATE_FAILED,
CONNECTION_STATE_OPEN
CONNECTION_STATE_FAILED
} from './consts.ts';
import {
createConnectionDiagnostics,
@ -106,7 +105,6 @@ export function createConnection<TChannels extends ConnectionChannelMap = Connec
let disposed = false;
let intentionalClose = false;
let connectPromise: Promise<ConnectionConnectResult> | null = null;
let lifecycle: ConnectionLifecycle;
function handleTransportOpen(): void {
@ -197,44 +195,34 @@ export function createConnection<TChannels extends ConnectionChannelMap = Connec
await channelRegistry.joinConfigured(reconnect, options.channels ?? {}, connection);
}
async function connectInternal(reconnect: boolean): Promise<ConnectionConnectResult> {
if (disposed) {
return {
ok: false,
state: stateTracker.state,
reason: CONNECTION_CONNECT_REASON_DISPOSED
};
}
if (stateTracker.state === CONNECTION_STATE_OPEN && isConnected()) {
return { ok: true, state: stateTracker.state, reused: true };
}
if (connectPromise !== null) return connectPromise;
connectPromise = (async () => {
const connector = createConnectionConnectController({
getState: () => stateTracker.state,
isDisposed: () => disposed,
isConnected,
beforeAttempt: () => {
intentionalClose = false;
try {
return await runConnectionConnect({
reconnect,
timers,
resolveTransport: transportRuntime.resolve,
attachTransport: transportRuntime.attach,
detachTransport: transportRuntime.detach,
markOpen: lifecycle.markOpen,
markClosedFailed: (error) => {
lifecycle.markClosed(CONNECTION_STATE_FAILED, error);
},
joinConfiguredChannels,
state: stateTracker,
requests,
sender,
diagnostics
});
} finally {
connectPromise = null;
}
})();
},
runConnect: (reconnect) =>
runConnectionConnect({
reconnect,
timers,
resolveTransport: transportRuntime.resolve,
attachTransport: transportRuntime.attach,
detachTransport: transportRuntime.detach,
markOpen: lifecycle.markOpen,
markClosedFailed: (error) => {
lifecycle.markClosed(CONNECTION_STATE_FAILED, error);
},
joinConfiguredChannels,
state: stateTracker,
requests,
sender,
diagnostics
})
});
return connectPromise;
async function connectInternal(reconnect: boolean): Promise<ConnectionConnectResult> {
return connector.connect(reconnect);
}
function closeTransport(reason: string): void {
@ -287,15 +275,10 @@ export function createConnection<TChannels extends ConnectionChannelMap = Connec
closeTransport(reason);
},
reconnect(reason = CONNECTION_CLOSE_REASON_RECONNECT) {
if (disposed) {
return Promise.resolve({
ok: false,
state: stateTracker.state,
reason: CONNECTION_CONNECT_REASON_DISPOSED
});
if (!disposed) {
closeTransport(reason);
intentionalClose = false;
}
closeTransport(reason);
intentionalClose = false;
return connectInternal(true);
},
reauthenticate() {

Loading…
Cancel
Save

Powered by TurnKey Linux.