mirror of
https://github.com/grpc/grpc-node.git
synced 2025-12-08 18:23:54 +00:00
Merge pull request #1614 from hugebdu/master
grpc-js: support adding/removing services on started server
This commit is contained in:
commit
d8021d20d9
@ -148,10 +148,6 @@ export class Server {
|
||||
service: ServiceDefinition,
|
||||
implementation: UntypedServiceImplementation
|
||||
): void {
|
||||
if (this.started === true) {
|
||||
throw new Error("Can't add a service to a started server.");
|
||||
}
|
||||
|
||||
if (
|
||||
service === null ||
|
||||
typeof service !== 'object' ||
|
||||
@ -212,6 +208,21 @@ export class Server {
|
||||
});
|
||||
}
|
||||
|
||||
removeService(service: ServiceDefinition): void {
|
||||
if (
|
||||
service === null ||
|
||||
typeof service !== 'object'
|
||||
) {
|
||||
throw new Error('removeService() requires object as argument');
|
||||
}
|
||||
|
||||
const serviceKeys = Object.keys(service);
|
||||
serviceKeys.forEach((name) => {
|
||||
const attrs = service[name];
|
||||
this.unregister(attrs.path);
|
||||
});
|
||||
}
|
||||
|
||||
bind(port: string, creds: ServerCredentials): void {
|
||||
throw new Error('Not implemented. Use bindAsync() instead');
|
||||
}
|
||||
@ -462,6 +473,10 @@ export class Server {
|
||||
return true;
|
||||
}
|
||||
|
||||
unregister(name: string): boolean {
|
||||
return this.handlers.delete(name);
|
||||
}
|
||||
|
||||
start(): void {
|
||||
if (
|
||||
this.http2ServerList.length === 0 ||
|
||||
@ -637,7 +652,7 @@ async function handleUnary<RequestType, ResponseType>(
|
||||
if (request === undefined || call.cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const emitter = new ServerUnaryCallImpl<RequestType, ResponseType>(
|
||||
call,
|
||||
metadata,
|
||||
|
||||
@ -202,7 +202,7 @@ describe('Server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('fails if the server has been started', done => {
|
||||
it('succeeds after server has been started', done => {
|
||||
const server = new Server();
|
||||
|
||||
server.bindAsync(
|
||||
@ -211,15 +211,131 @@ describe('Server', () => {
|
||||
(err, port) => {
|
||||
assert.ifError(err);
|
||||
server.start();
|
||||
assert.throws(() => {
|
||||
assert.doesNotThrow(() => {
|
||||
server.addService(mathServiceAttrs, dummyImpls);
|
||||
}, /Can't add a service to a started server\./);
|
||||
});
|
||||
server.tryShutdown(done);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeService', () => {
|
||||
let server: Server;
|
||||
let client: ServiceClient;
|
||||
|
||||
const mathProtoFile = path.join(__dirname, 'fixtures', 'math.proto');
|
||||
const mathClient = (loadProtoFile(mathProtoFile).math as any).Math;
|
||||
const mathServiceAttrs = mathClient.service;
|
||||
const dummyImpls = { div() {}, divMany() {}, fib() {}, sum() {} };
|
||||
|
||||
beforeEach(done => {
|
||||
server = new Server();
|
||||
server.addService(mathServiceAttrs, dummyImpls);
|
||||
server.bindAsync(
|
||||
'localhost:0',
|
||||
ServerCredentials.createInsecure(),
|
||||
(err, port) => {
|
||||
assert.ifError(err);
|
||||
client = new mathClient(
|
||||
`localhost:${port}`,
|
||||
grpc.credentials.createInsecure()
|
||||
);
|
||||
server.start();
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
client.close();
|
||||
server.tryShutdown(done);
|
||||
});
|
||||
|
||||
it('succeeds with a single service by removing all method handlers', done => {
|
||||
server.removeService(mathServiceAttrs);
|
||||
|
||||
let methodsVerifiedCount = 0;
|
||||
const methodsToVerify = Object.keys(mathServiceAttrs);
|
||||
|
||||
const assertFailsWithUnimplementedError = (error: ServiceError) => {
|
||||
assert(error);
|
||||
assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED);
|
||||
methodsVerifiedCount++;
|
||||
if (methodsVerifiedCount === methodsToVerify.length) {
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
methodsToVerify.forEach((method) => {
|
||||
const call = client[method]({}, assertFailsWithUnimplementedError); // for unary
|
||||
call.on('error', assertFailsWithUnimplementedError); // for streamed
|
||||
});
|
||||
});
|
||||
|
||||
it('fails for non-object service definition argument', () => {
|
||||
assert.throws(() => {
|
||||
server.removeService('upsie' as any)
|
||||
}, /removeService.*requires object as argument/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('unregister', () => {
|
||||
|
||||
let server: Server;
|
||||
let client: ServiceClient;
|
||||
|
||||
const mathProtoFile = path.join(__dirname, 'fixtures', 'math.proto');
|
||||
const mathClient = (loadProtoFile(mathProtoFile).math as any).Math;
|
||||
const mathServiceAttrs = mathClient.service;
|
||||
|
||||
beforeEach(done => {
|
||||
server = new Server();
|
||||
server.addService(mathServiceAttrs, {
|
||||
div(call: ServerUnaryCall<any, any>, callback: sendUnaryData<any>) {
|
||||
callback(null, {quotient: '42'});
|
||||
},
|
||||
});
|
||||
server.bindAsync(
|
||||
'localhost:0',
|
||||
ServerCredentials.createInsecure(),
|
||||
(err, port) => {
|
||||
assert.ifError(err);
|
||||
client = new mathClient(
|
||||
`localhost:${port}`,
|
||||
grpc.credentials.createInsecure()
|
||||
);
|
||||
server.start();
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
client.close();
|
||||
server.tryShutdown(done);
|
||||
});
|
||||
|
||||
it('removes handler by name and returns true', done => {
|
||||
const name = mathServiceAttrs['Div'].path;
|
||||
assert.strictEqual(server.unregister(name), true, 'Server#unregister should return true on success');
|
||||
|
||||
client.div(
|
||||
{ divisor: 4, dividend: 3 },
|
||||
(error: ServiceError, response: any) => {
|
||||
assert(error);
|
||||
assert.strictEqual(error.code, grpc.status.UNIMPLEMENTED);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('returns false for unknown handler', () => {
|
||||
assert.strictEqual(server.unregister('noOneHere'), false, 'Server#unregister should return false on failure');
|
||||
});
|
||||
});
|
||||
|
||||
it('throws when unimplemented methods are called', () => {
|
||||
const server = new Server();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user