Skip to content

Commit

Permalink
Merge pull request #2750 from murgatroid99/grpc-js_idle_uds_fix
Browse files Browse the repository at this point in the history
grpc-js: Fix UDS channels not reconnecting after going idle
  • Loading branch information
murgatroid99 authored May 15, 2024
2 parents 3105791 + 87a3541 commit 45e5fe5
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 20 deletions.
2 changes: 1 addition & 1 deletion packages/grpc-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@grpc/grpc-js",
"version": "1.10.7",
"version": "1.10.8",
"description": "gRPC Library for Node - pure JS implementation",
"homepage": "https://grpc.io/",
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",
Expand Down
2 changes: 1 addition & 1 deletion packages/grpc-js/src/resolver-uds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class UdsResolver implements Resolver {
}

destroy() {
// This resolver owns no resources, so we do nothing here.
this.hasReturnedResult = false;
}

static getDefaultAuthority(target: GrpcUri): string {
Expand Down
51 changes: 38 additions & 13 deletions packages/grpc-js/test/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import * as loader from '@grpc/proto-loader';
import * as assert2 from './assert2';
import * as path from 'path';
import * as grpc from '../src';
import * as fsPromises from 'fs/promises';
import * as os from 'os';

import {
GrpcObject,
Expand Down Expand Up @@ -71,54 +73,77 @@ const serviceImpl = {

export class TestServer {
private server: grpc.Server;
public port: number | null = null;
private target: string | null = null;
constructor(public useTls: boolean, options?: grpc.ServerOptions) {
this.server = new grpc.Server(options);
this.server.addService(echoService.service, serviceImpl);
}
start(): Promise<void> {
let credentials: grpc.ServerCredentials;

private getCredentials(): grpc.ServerCredentials {
if (this.useTls) {
credentials = grpc.ServerCredentials.createSsl(null, [
return grpc.ServerCredentials.createSsl(null, [
{ private_key: key, cert_chain: cert },
]);
} else {
credentials = grpc.ServerCredentials.createInsecure();
return grpc.ServerCredentials.createInsecure();
}
}

start(): Promise<void> {
return new Promise<void>((resolve, reject) => {
this.server.bindAsync('localhost:0', credentials, (error, port) => {
this.server.bindAsync('localhost:0', this.getCredentials(), (error, port) => {
if (error) {
reject(error);
return;
}
this.port = port;
this.target = `localhost:${port}`;
resolve();
});
});
}

startUds(): Promise<void> {
return fsPromises.mkdtemp(path.join(os.tmpdir(), 'uds')).then(dir => {
return new Promise<void>((resolve, reject) => {
const target = `unix://${dir}/socket`;
this.server.bindAsync(target, this.getCredentials(), (error, port) => {
if (error) {
reject(error);
return;
}
this.target = target;
resolve();
});
});
});
}

shutdown() {
this.server.forceShutdown();
}

getTarget() {
if (this.target === null) {
throw new Error('Server not yet started');
}
return this.target;
}
}

export class TestClient {
private client: ServiceClient;
constructor(port: number, useTls: boolean, options?: grpc.ChannelOptions) {
constructor(target: string, useTls: boolean, options?: grpc.ChannelOptions) {
let credentials: grpc.ChannelCredentials;
if (useTls) {
credentials = grpc.credentials.createSsl(ca);
} else {
credentials = grpc.credentials.createInsecure();
}
this.client = new echoService(`localhost:${port}`, credentials, options);
this.client = new echoService(target, credentials, options);
}

static createFromServer(server: TestServer, options?: grpc.ChannelOptions) {
if (server.port === null) {
throw new Error('Cannot create client, server not started');
}
return new TestClient(server.port, server.useTls, options);
return new TestClient(server.getTarget(), server.useTls, options);
}

waitForReady(deadline: grpc.Deadline, callback: (error?: Error) => void) {
Expand Down
41 changes: 41 additions & 0 deletions packages/grpc-js/test/test-idle-timer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,47 @@ describe('Channel idle timer', () => {
});
});

describe('Channel idle timer with UDS', () => {
let server: TestServer;
let client: TestClient | null = null;
before(() => {
server = new TestServer(false);
return server.startUds();
});
afterEach(() => {
if (client) {
client.close();
client = null;
}
});
after(() => {
server.shutdown();
});
it('Should be able to make a request after going idle', function (done) {
this.timeout(5000);
client = TestClient.createFromServer(server, {
'grpc.client_idle_timeout_ms': 1000,
});
client.sendRequest(error => {
assert.ifError(error);
assert.strictEqual(
client!.getChannelState(),
grpc.connectivityState.READY
);
setTimeout(() => {
assert.strictEqual(
client!.getChannelState(),
grpc.connectivityState.IDLE
);
client!.sendRequest(error => {
assert.ifError(error);
done();
});
}, 1100);
});
});
});

describe('Server idle timer', () => {
let server: TestServer;
let client: TestClient | null = null;
Expand Down
2 changes: 1 addition & 1 deletion packages/grpc-js/test/test-pick-first.ts
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,7 @@ describe('pick_first load balancing policy', () => {
before(async () => {
server = new TestServer(false);
await server.start();
client = new TestClient(server.port!, false, {
client = TestClient.createFromServer(server, {
'grpc.service_config': JSON.stringify(serviceConfig),
});
});
Expand Down
8 changes: 4 additions & 4 deletions packages/grpc-js/test/test-server-interceptors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ describe('Server interceptors', () => {
grpc.ServerCredentials.createInsecure(),
(error, port) => {
assert.ifError(error);
client = new TestClient(port, false);
client = new TestClient(`localhost:${port}`, false);
done();
}
);
Expand Down Expand Up @@ -195,7 +195,7 @@ describe('Server interceptors', () => {
grpc.ServerCredentials.createInsecure(),
(error, port) => {
assert.ifError(error);
client = new TestClient(port, false);
client = new TestClient(`localhost:${port}`, false);
done();
}
);
Expand Down Expand Up @@ -246,7 +246,7 @@ describe('Server interceptors', () => {
grpc.ServerCredentials.createInsecure(),
(error, port) => {
assert.ifError(error);
client = new TestClient(port, false);
client = new TestClient(`localhost:${port}`, false);
done();
}
);
Expand Down Expand Up @@ -292,7 +292,7 @@ describe('Server interceptors', () => {
grpc.ServerCredentials.createInsecure(),
(error, port) => {
assert.ifError(error);
client = new TestClient(port, false);
client = new TestClient(`localhost:${port}`, false);
done();
}
);
Expand Down

0 comments on commit 45e5fe5

Please sign in to comment.