Skip to content

Commit

Permalink
feat: added optional timeout timers to NodeConnectionManager methods
Browse files Browse the repository at this point in the history
In some cases we want to specify how long we attempt to connect to a node on a per-connection basis.

Related #363
  • Loading branch information
tegefaulkes committed Jun 7, 2022
1 parent 7afb297 commit fc27871
Show file tree
Hide file tree
Showing 15 changed files with 143 additions and 80 deletions.
8 changes: 4 additions & 4 deletions src/PolykeyClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FileSystem } from './types';
import type { FileSystem, Timer } from './types';
import type { NodeId } from './nodes/types';
import type { Host, Port } from './network/types';

Expand Down Expand Up @@ -29,7 +29,7 @@ class PolykeyClient {
nodePath = config.defaults.nodePath,
session,
grpcClient,
timeout,
timer,
fs = require('fs'),
logger = new Logger(this.name),
fresh = false,
Expand All @@ -38,7 +38,7 @@ class PolykeyClient {
host: Host;
port: Port;
nodePath?: string;
timeout?: number;
timer?: Timer;
session?: Session;
grpcClient?: GRPCClientClient;
fs?: FileSystem;
Expand Down Expand Up @@ -66,7 +66,7 @@ class PolykeyClient {
port,
tlsConfig: { keyPrivatePem: undefined, certChainPem: undefined },
session,
timeout,
timer,
logger: logger.getChild(GRPCClientClient.name),
}));
const pkClient = new PolykeyClient({
Expand Down
7 changes: 4 additions & 3 deletions src/agent/GRPCClientAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type * as utilsPB from '../proto/js/polykey/v1/utils/utils_pb';
import type * as vaultsPB from '../proto/js/polykey/v1/vaults/vaults_pb';
import type * as nodesPB from '../proto/js/polykey/v1/nodes/nodes_pb';
import type * as notificationsPB from '../proto/js/polykey/v1/notifications/notifications_pb';
import type { Timer } from '../types';
import Logger from '@matrixai/logger';
import { CreateDestroy, ready } from '@matrixai/async-init/dist/CreateDestroy';
import * as agentErrors from './errors';
Expand All @@ -32,7 +33,7 @@ class GRPCClientAgent extends GRPCClient<AgentServiceClient> {
port,
tlsConfig,
proxyConfig,
timeout = Infinity,
timer,
destroyCallback = async () => {},
logger = new Logger(this.name),
}: {
Expand All @@ -41,7 +42,7 @@ class GRPCClientAgent extends GRPCClient<AgentServiceClient> {
port: Port;
tlsConfig?: Partial<TLSConfig>;
proxyConfig?: ProxyConfig;
timeout?: number;
timer?: Timer;
destroyCallback?: () => Promise<void>;
logger?: Logger;
}): Promise<GRPCClientAgent> {
Expand All @@ -53,7 +54,7 @@ class GRPCClientAgent extends GRPCClient<AgentServiceClient> {
port,
tlsConfig,
proxyConfig,
timeout,
timer,
logger,
});
const grpcClientAgent = new GRPCClientAgent({
Expand Down
7 changes: 4 additions & 3 deletions src/client/GRPCClientClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type * as identitiesPB from '../proto/js/polykey/v1/identities/identities
import type * as keysPB from '../proto/js/polykey/v1/keys/keys_pb';
import type * as permissionsPB from '../proto/js/polykey/v1/permissions/permissions_pb';
import type * as secretsPB from '../proto/js/polykey/v1/secrets/secrets_pb';
import type { Timer } from '../types';
import { CreateDestroy, ready } from '@matrixai/async-init/dist/CreateDestroy';
import Logger from '@matrixai/logger';
import * as clientErrors from './errors';
Expand All @@ -38,7 +39,7 @@ class GRPCClientClient extends GRPCClient<ClientServiceClient> {
tlsConfig,
proxyConfig,
session,
timeout = Infinity,
timer,
destroyCallback = async () => {},
logger = new Logger(this.name),
}: {
Expand All @@ -48,7 +49,7 @@ class GRPCClientClient extends GRPCClient<ClientServiceClient> {
tlsConfig?: Partial<TLSConfig>;
proxyConfig?: ProxyConfig;
session?: Session;
timeout?: number;
timer?: Timer;
destroyCallback?: () => Promise<void>;
logger?: Logger;
}): Promise<GRPCClientClient> {
Expand All @@ -64,7 +65,7 @@ class GRPCClientClient extends GRPCClient<ClientServiceClient> {
port,
tlsConfig,
proxyConfig,
timeout,
timer,
interceptors,
logger,
});
Expand Down
17 changes: 13 additions & 4 deletions src/grpc/GRPCClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
import type { NodeId } from '../nodes/types';
import type { Certificate } from '../keys/types';
import type { Host, Port, TLSConfig, ProxyConfig } from '../network/types';
import type { Timer } from '../types';
import http2 from 'http2';
import Logger from '@matrixai/logger';
import * as grpc from '@grpc/grpc-js';
Expand Down Expand Up @@ -44,7 +45,7 @@ abstract class GRPCClient<T extends Client = Client> {
port,
tlsConfig,
proxyConfig,
timeout = Infinity,
timer,
interceptors = [],
logger = new Logger(this.name),
}: {
Expand All @@ -58,7 +59,7 @@ abstract class GRPCClient<T extends Client = Client> {
port: Port;
tlsConfig?: Partial<TLSConfig>;
proxyConfig?: ProxyConfig;
timeout?: number;
timer?: Timer;
interceptors?: Array<Interceptor>;
logger?: Logger;
}): Promise<{
Expand Down Expand Up @@ -123,9 +124,17 @@ abstract class GRPCClient<T extends Client = Client> {
}
const waitForReady = promisify(client.waitForReady).bind(client);
// Add the current unix time because grpc expects the milliseconds since unix epoch
timeout += Date.now();
try {
await waitForReady(timeout);
if (timer != null) {
await Promise.race([timer.timerP, waitForReady(Infinity)]);
// If the timer resolves first we throw a timeout error
if (timer?.timedOut === true) {
throw new grpcErrors.ErrorGRPCClientTimeout();
}
} else {
// No timer given so we wait forever
await waitForReady(Infinity);
}
} catch (e) {
// If we fail here then we leak the client object...
client.close();
Expand Down
7 changes: 4 additions & 3 deletions src/nodes/NodeConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { Certificate, PublicKey, PublicKeyPem } from '../keys/types';
import type Proxy from '../network/Proxy';
import type GRPCClient from '../grpc/GRPCClient';
import type NodeConnectionManager from './NodeConnectionManager';
import type { Timer } from '../types';
import Logger from '@matrixai/logger';
import { CreateDestroy, ready } from '@matrixai/async-init/dist/CreateDestroy';
import * as asyncInit from '@matrixai/async-init';
Expand Down Expand Up @@ -38,7 +39,7 @@ class NodeConnection<T extends GRPCClient> {
targetHost,
targetPort,
targetHostname,
connConnectTime = 20000,
timer,
proxy,
keyManager,
clientFactory,
Expand All @@ -50,7 +51,7 @@ class NodeConnection<T extends GRPCClient> {
targetHost: Host;
targetPort: Port;
targetHostname?: Hostname;
connConnectTime?: number;
timer?: Timer;
proxy: Proxy;
keyManager: KeyManager;
clientFactory: (...args) => Promise<T>;
Expand Down Expand Up @@ -125,7 +126,7 @@ class NodeConnection<T extends GRPCClient> {
await nodeConnection.destroy();
}
},
timeout: connConnectTime,
timer: timer,
}),
holePunchPromises,
]);
Expand Down
Loading

0 comments on commit fc27871

Please sign in to comment.