diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6d279ee0..95ffdf4a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,9 @@
### unreleased changes
-none
+Breaking changes:
+
+- `RpcOptions` takes a `timeout` property now. `deadline` property
+ has been removed. See #138 for details.
### v2.0.0-alpha.29
diff --git a/MANUAL.md b/MANUAL.md
index 65c551e2..af07b6d7 100644
--- a/MANUAL.md
+++ b/MANUAL.md
@@ -1409,10 +1409,9 @@ The options:
If a key ends with `-bin`, it should contain binary data in base64
encoding, allowing you to send serialized messages.
-- `deadline: Date | number`
-
- Deadline for the call. Can be a specific date or a
- timeout in milliseconds.
+- `timeout: Date | number`
+ Timeout for the call in milliseconds.
+ If a Date object is given, it is used as a deadline.
- `interceptors: RpcInterceptor[]`
diff --git a/packages/example-angular-app/src/app/grpcweb-server-streaming/grpcweb-server-streaming.component.html b/packages/example-angular-app/src/app/grpcweb-server-streaming/grpcweb-server-streaming.component.html
index fd0213f6..066b174c 100644
--- a/packages/example-angular-app/src/app/grpcweb-server-streaming/grpcweb-server-streaming.component.html
+++ b/packages/example-angular-app/src/app/grpcweb-server-streaming/grpcweb-server-streaming.component.html
@@ -19,7 +19,7 @@
GrpcWebOptions:
-
diff --git a/packages/example-angular-app/src/app/grpcweb-server-streaming/grpcweb-server-streaming.component.ts b/packages/example-angular-app/src/app/grpcweb-server-streaming/grpcweb-server-streaming.component.ts
index f1bec6c2..e4d47c7b 100644
--- a/packages/example-angular-app/src/app/grpcweb-server-streaming/grpcweb-server-streaming.component.ts
+++ b/packages/example-angular-app/src/app/grpcweb-server-streaming/grpcweb-server-streaming.component.ts
@@ -25,7 +25,7 @@ export class GrpcwebServerStreamingComponent {
readonly options: GrpcWebOptions = {
baseUrl: 'http://localhost:5080',
- deadline: Date.now() + 2000,
+ timeout: Date.now() + 2000,
format: 'binary',
// simple example for how to add auth headers to each request
diff --git a/packages/example-angular-app/src/app/grpcweb-unary/grpcweb-unary.component.html b/packages/example-angular-app/src/app/grpcweb-unary/grpcweb-unary.component.html
index bd50801e..62216c48 100644
--- a/packages/example-angular-app/src/app/grpcweb-unary/grpcweb-unary.component.html
+++ b/packages/example-angular-app/src/app/grpcweb-unary/grpcweb-unary.component.html
@@ -19,7 +19,7 @@
GrpcWebOptions:
-
diff --git a/packages/example-node-grpcweb-transport-client/client.ts b/packages/example-node-grpcweb-transport-client/client.ts
index 5d9401a0..87dd8005 100644
--- a/packages/example-node-grpcweb-transport-client/client.ts
+++ b/packages/example-node-grpcweb-transport-client/client.ts
@@ -65,7 +65,7 @@ async function callServerStream(client: IExampleServiceClient) {
const headers = await call.headers;
console.log("got response headers: ", headers)
- for await (let response of call.response) {
+ for await (let response of call.responses) {
console.log("got response message: ", response)
}
diff --git a/packages/grpc-transport/src/grpc-transport.ts b/packages/grpc-transport/src/grpc-transport.ts
index 3a1d978d..9ec47ed1 100644
--- a/packages/grpc-transport/src/grpc-transport.ts
+++ b/packages/grpc-transport/src/grpc-transport.ts
@@ -45,9 +45,13 @@ export class GrpcTransport implements RpcTransport {
if (options.callOptions) {
return options.callOptions;
}
- return {
- deadline: options.deadline
- };
+ const co: CallOptions = {};
+ if (typeof options.timeout === "number") {
+ co.deadline = Date.now() + options.timeout;
+ } else if (options.timeout) {
+ co.deadline = options.timeout;
+ }
+ return co;
}
unary(method: MethodInfo, input: I, options: GrpcCallOptions): UnaryCall {
diff --git a/packages/grpcweb-transport/src/grpc-web-format.ts b/packages/grpcweb-transport/src/grpc-web-format.ts
index 84c568cd..f0dfee66 100644
--- a/packages/grpcweb-transport/src/grpc-web-format.ts
+++ b/packages/grpcweb-transport/src/grpc-web-format.ts
@@ -6,7 +6,7 @@ import {GrpcStatusCode} from "./goog-grpc-status-code";
/**
* Create fetch API headers for a grpc-web request.
*/
-export function createGrpcWebRequestHeader(headers: Headers, format: GrpcWebFormat, deadline: Date | number | undefined, meta?: RpcMetadata, userAgent?: string): Headers {
+export function createGrpcWebRequestHeader(headers: Headers, format: GrpcWebFormat, timeout: Date | number | undefined, meta?: RpcMetadata, userAgent?: string): Headers {
// add meta as headers
if (meta) {
for (let [k, v] of Object.entries(meta)) {
@@ -28,15 +28,23 @@ export function createGrpcWebRequestHeader(headers: Headers, format: GrpcWebForm
headers.set('X-Grpc-Web', "1");
if (userAgent)
headers.set("X-User-Agent", userAgent);
- if (deadline) {
- let ts = typeof deadline == "number" ? deadline : deadline.getTime();
- let timeout = ts - Date.now();
- headers.set('grpc-timeout', timeout + 'm');
+
+ if (typeof timeout === "number") {
+ if (timeout <= 0) {
+ // we raise an error ourselves because header "grpc-timeout" must be a positive integer
+ throw new RpcError(`timeout ${timeout} ms exceeded`, GrpcStatusCode[GrpcStatusCode.DEADLINE_EXCEEDED]);
+ }
+ headers.set('grpc-timeout', `${timeout}m`);
+ } else if (timeout) {
+ const deadline = timeout.getTime();
+ const now = Date.now();
+ if (deadline <= now) {
+ // we raise an error ourselves because header "grpc-timeout" must be a positive integer
+ throw new RpcError(`deadline ${timeout} exceeded`, GrpcStatusCode[GrpcStatusCode.DEADLINE_EXCEEDED]);
+ }
+ headers.set('grpc-timeout', `${deadline - now}m`);
}
- // let timeout = typeof deadline == "number" ? deadline : deadline instanceof Date ? (deadline.getTime() - Date.now()) : 0;
- // if (timeout > 0) {
- // headers.set('grpc-timeout', timeout + 'm');
- // }
+
return headers;
}
diff --git a/packages/grpcweb-transport/src/grpc-web-transport.ts b/packages/grpcweb-transport/src/grpc-web-transport.ts
index 33390afe..eef328d3 100644
--- a/packages/grpcweb-transport/src/grpc-web-transport.ts
+++ b/packages/grpcweb-transport/src/grpc-web-transport.ts
@@ -97,7 +97,7 @@ export class GrpcWebFetchTransport implements RpcTransport {
globalThis.fetch(url, {
...fetchInit,
method: 'POST',
- headers: createGrpcWebRequestHeader(new globalThis.Headers(), format, opt.deadline, opt.meta),
+ headers: createGrpcWebRequestHeader(new globalThis.Headers(), format, opt.timeout, opt.meta),
body: createGrpcWebRequestBody(inputBytes, format),
signal: options.abort ?? null // node-fetch@3.0.0-beta.9 rejects `undefined`
})
@@ -197,7 +197,7 @@ export class GrpcWebFetchTransport implements RpcTransport {
globalThis.fetch(url, {
...fetchInit,
method: 'POST',
- headers: createGrpcWebRequestHeader(new globalThis.Headers(), format, opt.deadline, opt.meta),
+ headers: createGrpcWebRequestHeader(new globalThis.Headers(), format, opt.timeout, opt.meta),
body: createGrpcWebRequestBody(inputBytes, format),
signal: options.abort ?? null // node-fetch@3.0.0-beta.9 rejects `undefined`
})
diff --git a/packages/runtime-rpc/spec/rpc-options.spec.ts b/packages/runtime-rpc/spec/rpc-options.spec.ts
index 495e4fa6..e9f00f43 100644
--- a/packages/runtime-rpc/spec/rpc-options.spec.ts
+++ b/packages/runtime-rpc/spec/rpc-options.spec.ts
@@ -5,8 +5,8 @@ import type {IMessageType} from "@protobuf-ts/runtime";
describe('mergeRpcOptions()', () => {
it('does not require seconds argument', function () {
- let opt = mergeRpcOptions({deadline: 123}, undefined);
- expect(opt).toEqual({deadline: 123});
+ let opt = mergeRpcOptions({timeout: 123}, undefined);
+ expect(opt).toEqual({timeout: 123});
});
it('merges interceptors', function () {
diff --git a/packages/runtime-rpc/src/rpc-options.ts b/packages/runtime-rpc/src/rpc-options.ts
index ab5029cd..e36bc149 100644
--- a/packages/runtime-rpc/src/rpc-options.ts
+++ b/packages/runtime-rpc/src/rpc-options.ts
@@ -23,10 +23,10 @@ export interface RpcOptions {
meta?: RpcMetadata;
/**
- * Deadline for the call. Can be given as a Date object or a
- * timestamp in milliseconds.
+ * Timeout for the call in milliseconds.
+ * If a Date object is given, it is used as a deadline.
*/
- deadline?: Date | number;
+ timeout?: number | Date;
/**
* Interceptors can be used to manipulate request and response data.