Line data Source code
1 : import * as connection from '@ankoh/dashql-jsonschema/connection.js';
2 :
3 : import type { DetailedError } from '../../utils/error.js';
4 :
5 : import { VariantKind } from '../../utils/variant.js';
6 : import { HyperDatabaseChannel } from './hyperdb_grpc_client.js';
7 : import { HYPER_CONNECTOR } from '../connector_info.js';
8 : import {
9 : ConnectionHealth,
10 : ConnectionStatus,
11 : ConnectionState,
12 : RESET_CONNECTION,
13 : DELETE_CONNECTION,
14 : } from '../connection_state.js';
15 : import { dateToTimestamp } from "../proto_helper.js";
16 :
17 : export interface HyperConnectionDetails {
18 : /// The protobuf
19 : proto: connection.HyperConnectionDetails;
20 : /// The hyper channel
21 : channel: HyperDatabaseChannel | null;
22 : }
23 :
24 1 : export function createHyperConnectionStateDetails(params: connection.HyperConnectionParams): HyperConnectionDetails {
25 1 : return {
26 1 : proto: {
27 1 : setupTimings: {},
28 1 : setupParams: params,
29 1 : },
30 1 : channel: null
31 1 : };
32 1 : }
33 :
34 : export function getHyperConnectionDetails(state: ConnectionState | null): HyperConnectionDetails | null {
35 : if (state == null) return null;
36 : switch (state.details.type) {
37 : case HYPER_CONNECTOR: return state.details.value;
38 : default: return null;
39 : }
40 : }
41 :
42 1 : export const HYPER_CHANNEL_SETUP_CANCELLED = Symbol('HYPER_CHANNEL_SETUP_CANCELLED');
43 1 : export const HYPER_CHANNEL_SETUP_FAILED = Symbol('HYPER_CHANNEL_SETUP_FAILED');
44 1 : export const HYPER_CHANNEL_SETUP_STARTED = Symbol('HYPER_CHANNEL_SETUP_STARTED');
45 1 : export const HYPER_CHANNEL_READY = Symbol('HYPER_CHANNEL_READY');
46 :
47 : export type HyperConnectorAction =
48 : | VariantKind<typeof RESET_CONNECTION, null>
49 : | VariantKind<typeof DELETE_CONNECTION, null>
50 : | VariantKind<typeof HYPER_CHANNEL_SETUP_STARTED, connection.HyperConnectionParams>
51 : | VariantKind<typeof HYPER_CHANNEL_SETUP_CANCELLED, DetailedError>
52 : | VariantKind<typeof HYPER_CHANNEL_SETUP_FAILED, DetailedError>
53 : | VariantKind<typeof HYPER_CHANNEL_READY, [HyperDatabaseChannel, connection.HyperConnectionParams]>
54 : ;
55 :
56 1 : export function reduceHyperConnectorState(state: ConnectionState, action: HyperConnectorAction): ConnectionState | null {
57 1 : const details = state.details.value as HyperConnectionDetails;
58 1 : let next: ConnectionState | null = null;
59 1 : switch (action.type) {
60 1 : case DELETE_CONNECTION:
61 1 : case RESET_CONNECTION:
62 1 : details.channel?.close();
63 1 : next = {
64 1 : ...state,
65 1 : details: {
66 1 : type: HYPER_CONNECTOR,
67 1 : value: {
68 1 : ...details,
69 1 : proto: {
70 1 : ...details.proto,
71 1 : setupTimings: {},
72 1 : channelError: undefined,
73 1 : healthCheckError: undefined,
74 1 : },
75 1 : channel: null
76 1 : }
77 1 : },
78 1 : };
79 1 : break;
80 1 : case HYPER_CHANNEL_SETUP_CANCELLED:
81 1 : next = {
82 1 : ...state,
83 1 : connectionStatus: ConnectionStatus.CHANNEL_SETUP_CANCELLED,
84 1 : connectionHealth: ConnectionHealth.CANCELLED,
85 1 : details: {
86 1 : type: HYPER_CONNECTOR,
87 1 : value: {
88 1 : ...details,
89 1 : proto: {
90 1 : ...details.proto,
91 1 : setupTimings: {
92 1 : ...details.proto.setupTimings,
93 1 : channelSetupCancelledAt: dateToTimestamp(new Date()),
94 1 : },
95 1 : setupParams: details.proto.setupParams,
96 1 : channelError: action.value,
97 1 : healthCheckError: undefined,
98 1 : },
99 1 : channel: null
100 1 : }
101 1 : },
102 1 : };
103 1 : break;
104 1 : case HYPER_CHANNEL_SETUP_FAILED:
105 1 : next = {
106 1 : ...state,
107 1 : connectionStatus: ConnectionStatus.CHANNEL_SETUP_FAILED,
108 1 : connectionHealth: ConnectionHealth.FAILED,
109 1 : details: {
110 1 : type: HYPER_CONNECTOR,
111 1 : value: {
112 1 : ...details,
113 1 : proto: {
114 1 : ...details.proto,
115 1 : setupTimings: {
116 1 : ...details.proto.setupTimings,
117 1 : channelSetupFailedAt: dateToTimestamp(new Date()),
118 1 : },
119 1 : channelError: action.value,
120 1 : },
121 1 : channel: null
122 1 : }
123 1 : },
124 1 : };
125 1 : break;
126 1 : case HYPER_CHANNEL_SETUP_STARTED: {
127 1 : const details: HyperConnectionDetails = {
128 1 : proto: {
129 1 : setupTimings: {
130 1 : channelSetupStartedAt: dateToTimestamp(new Date()),
131 1 : },
132 1 : setupParams: action.value,
133 1 : channelError: undefined,
134 1 : healthCheckError: undefined,
135 1 : },
136 1 : channel: null,
137 1 : };
138 1 : next = {
139 1 : ...state,
140 1 : connectionStatus: ConnectionStatus.CHANNEL_SETUP_STARTED,
141 1 : connectionHealth: ConnectionHealth.CONNECTING,
142 1 : details: {
143 1 : type: HYPER_CONNECTOR,
144 1 : value: details,
145 1 : },
146 1 : };
147 1 : break;
148 1 : }
149 1 : case HYPER_CHANNEL_READY:
150 1 : const [channel, setupParams] = action.value;
151 1 : next = {
152 1 : ...state,
153 1 : connectionStatus: ConnectionStatus.CHANNEL_READY,
154 1 : connectionHealth: setupParams.protocol === 'WASM'
155 1 : ? ConnectionHealth.ONLINE
156 1 : : ConnectionHealth.CONNECTING,
157 1 : details: {
158 1 : type: HYPER_CONNECTOR,
159 1 : value: {
160 1 : ...details,
161 1 : proto: {
162 1 : ...details.proto,
163 1 : setupParams,
164 1 : setupTimings: {
165 1 : ...details.proto.setupTimings,
166 1 : channelReadyAt: dateToTimestamp(new Date()),
167 1 : },
168 1 : },
169 1 : channel,
170 1 : }
171 1 : },
172 1 : };
173 : break;
174 1 : }
175 1 : return next;
176 1 : }
|