use of io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.session_pb.HandshakeResponse in project deephaven-core by deephaven.
the class WorkerConnection method connectToWorker.
/**
* Creates a new session based on the current auth info, and attempts to re-create all tables and other objects that
* were currently open.
*
* First we assume that the auth token provider is valid, and ask for a new token to provide to the worker.
*
* Given that token, we create a new session on the worker server.
*
* When a table is first fetched, it might fail - the worker connection will keep trying to connect even if the
* failure is in one of the above steps. A later attempt to fetch that table may succeed however.
*
* Once the table has been successfully fetched, after each reconnect until the table is close()d we'll attempt to
* restore the table by re-fetching the table, then reapplying all operations on it.
*/
private void connectToWorker(Supplier<Promise<ConnectToken>> authTokenPromiseSupplier) {
info.running().then(queryWorkerRunning -> {
// get the auth token
return authTokenPromiseSupplier.get();
}).then(authToken -> {
// create a new session
HandshakeRequest handshakeRequest = new HandshakeRequest();
if (authToken != null) {
Uint8Array token = new Uint8Array(authToken.getBytes().length);
handshakeRequest.setPayload(token);
}
handshakeRequest.setAuthProtocol(1);
return Callbacks.<HandshakeResponse, Object>grpcUnaryPromise(c -> sessionServiceClient.newSession(handshakeRequest, (BrowserHeaders) null, c::apply));
}).then(handshakeResponse -> {
// start the reauth cycle
authUpdate(handshakeResponse);
// subscribe to fatal errors
subscribeToTerminationNotification();
state = State.Connected;
JsLog.debug("Connected to worker, ensuring all states are refreshed");
// mark that we succeeded
newSessionReconnect.success();
// nuke pending callbacks, we'll remake them
handleCallbacks = new JsWeakMap<>();
definitionCallbacks = new JsWeakMap<>();
// for each cts in the cache, get all with active subs
ClientTableState[] hasActiveSubs = cache.getAllStates().stream().peek(cts -> {
cts.getHandle().setConnected(false);
cts.setSubscribed(false);
cts.forActiveLifecycles(item -> {
assert !(item instanceof JsTable) || ((JsTable) item).state() == cts : "Invalid table state " + item + " does not point to state " + cts;
item.suppressEvents();
});
}).filter(cts -> !cts.isEmpty()).peek(cts -> {
cts.forActiveTables(t -> {
assert t.state().isAncestor(cts) : "Invalid binding " + t + " (" + t.state() + ") does not contain " + cts;
});
}).toArray(ClientTableState[]::new);
// clear caches
List<ClientTableState> inactiveStatesToRemove = cache.getAllStates().stream().filter(ClientTableState::isEmpty).collect(Collectors.toList());
inactiveStatesToRemove.forEach(cache::release);
flushable.clear();
reviver.revive(metadata, hasActiveSubs);
tableMaps.forEach((handle, tableMap) -> tableMap.refetch());
figures.forEach((p0, p1, p2) -> p0.refetch());
info.connected();
// if any tables have been requested, make sure they start working now that we are connected
onOpen.forEach(c -> c.onSuccess(null));
onOpen.clear();
// // start a heartbeat to check if connection is properly alive
// ping(success.getAuthSessionToken());
startExportNotificationsStream();
return Promise.resolve(handshakeResponse);
}, fail -> {
// this is non-recoverable, connection/auth/registration failed, but we'll let it start again when
// state changes
state = State.Failed;
JsLog.debug("Failed to connect to worker.");
final String failure = fail.toString();
// notify all pending fetches that they failed
onOpen.forEach(c -> c.onFailure(failure));
onOpen.clear();
// if (server != null) {
// // explicitly disconnect from the query worker
// server.close();
// }
// signal that we should try again
newSessionReconnect.failed();
// inform the UI that it failed to connect
info.failureHandled("Failed to connect: " + failure);
return null;
});
}
Aggregations