Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An experimental grpc module graduation #1472

Merged
merged 4 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
---
title: "grpc"
excerpt: "Experimental GRPC module"
weight: 02
title: 'grpc'
excerpt: 'Experimental GRPC module'
weight: 02
---

# grpc

{{< docs/shared source="k6" lookup="experimental-module.md" version="<K6_VERSION>" >}}
{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

The `k6/experimental/grpc` module is an extension of the [`k6/net/grpc`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc). It provides a [gRPC](https://grpc.io/) client for Remote Procedure Calls (RPC) over HTTP/2.

The key-difference between the two modules is new `Stream` class, which provides client and server streaming support. Our long-term goal is to make this module part of k6 core, and long-term to replace the [`k6/net/grpc`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc) module.
Prior k6 `v0.49` the key-difference between the two modules was streaming support, but it has been added to the `k6/net/grpc` module as well. We recommend using the `k6/net/grpc` module.
olegbespalov marked this conversation as resolved.
Show resolved Hide resolved

| Class/Method | Description |
| ------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ weight: 10

# Client

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

`Client` is a gRPC client that can interact with a gRPC server.

| Method | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ weight: 40

# Client.close()

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

Close the connection to the gRPC service. Tear down all underlying connections.

### Examples
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ weight: 20

# Client.connect(address [,params])

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

Opens a connection to a gRPC server; will block until a connection is made or a connection error is thrown. Cannot be called during the [`init` phase](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/test-lifecycle).

See [Client.close()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-experimental/grpc/client/client-close) to close the connection.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ weight: 30

# Client.invoke(url, request [,params])

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

Invokes an unary RPC request to the given method.

The given method to invoke must have its RPC schema previously loaded via the [Client.load()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-experimental/grpc/client/client-load) function, otherwise an
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ weight: 11

# Client.loadProtoset(protosetPath)

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

Loads and parses the protoset file (serialized FileDescriptor set) so they are available to the client to marshal/unmarshal the correct request and response data structures for the RPC schema.

Must be called within the [`init` phase](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/test-lifecycle).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ weight: 10

# Client.load(importPaths, ...protoFiles)

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

Loads and parses the protocol buffer descriptors so they are available to the client to marshal/unmarshal the correct request and response data structures for the RPC schema.

Must be called within the [`init` phase](https://grafana.com/docs/k6/<K6_VERSION>/using-k6/test-lifecycle).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ weight: 40

# Constants

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

Define constants to distinguish between [gRPC Response](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-experimental/grpc/response) statuses.

| Constant | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ weight: 20

# Params

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

_Params_ is an object used by the gRPC methods that generate RPC requests. _Params_ contains request-specific options like headers that should be inserted into the request.

| Name | Type | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ weight: 30

# Response

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

| Name | Type | Description |
| ------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Response.status` | number | The response gRPC status code. Use the gRPC [status constants](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-experimental/grpc/constants) to check equality. |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
---
title: Stream
excerpt: 'GRPC Streams'
weight: 50
weight: 30
---

# Stream

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

Using a GRPC client creates a stream. An important note that the client should be already connected (client.connect called) to the server before creating a stream.

| Method | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ weight: 40

# Stream.end()

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

Signals to the server that the client has finished sending messages.

### Example
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ weight: 15

# Error

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

The error object is the object that is passed to the `error` event handler function.

| Name | Type | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ weight: 10

# Stream.on()

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

Set up handler functions for various events on the GRPC stream.

| Parameter | Type | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ weight: 40

# Stream.write()

{{< docs/shared source="k6" lookup="experimental-grpc-module.md" version="<K6_VERSION>" >}}

Writes a message to the stream.

### Example
Expand Down
8 changes: 5 additions & 3 deletions docs/sources/next/javascript-api/k6-net-grpc/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ weight: 11

# k6/net/grpc

{{< docs/shared source="k6" lookup="grpc-module.md" version="<K6_VERSION>" >}}

The `k6/net/grpc` module provides a [gRPC](https://grpc.io/) client for Remote Procedure Calls (RPC) over HTTP/2.
The `k6/net/grpc` module provides a [gRPC](https://grpc.io/) client for Remote Procedure Calls (RPC) over HTTP/2. It supports unary and streaming (starting [v0.49](https://github.com/grafana/k6/releases/tag/v0.49.0)) RPCs.
olegbespalov marked this conversation as resolved.
Show resolved Hide resolved

| Class/Method | Description |
| --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand All @@ -20,6 +18,10 @@ The `k6/net/grpc` module provides a [gRPC](https://grpc.io/) client for Remote P
| [Params](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/params) | RPC Request specific options. |
| [Response](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/response) | Returned by RPC requests. |
| [Constants](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/constants) | Define constants to distinguish between [gRPC Response](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/response) statuses. |
| [Stream](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/stream) | Creates a new GRPC stream. |
| [Stream.on(event, handler)](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/stream/stream-on) | Adds a new listener to one of the possible stream event's. |
olegbespalov marked this conversation as resolved.
Show resolved Hide resolved
| [Stream.write(message)](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/stream/stream-write) | Writes a message to the stream. |
| [Stream.end()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/stream/stream-end) | Signals to server that client finished sending. |
olegbespalov marked this conversation as resolved.
Show resolved Hide resolved

## gRPC metrics

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
title: Client
excerpt: 'Client is a gRPC client that can interact with a gRPC server.'
weight: 10
weight: 20
---

# Client

{{< docs/shared source="k6" lookup="grpc-module.md" version="<K6_VERSION>" >}}

`Client` is a gRPC client that can interact with a gRPC server. Only unary RPCs are currently supported in this module.
`Client` is a gRPC client that can interact with a gRPC server.

| Method | Description |
| ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand Down
204 changes: 204 additions & 0 deletions docs/sources/next/javascript-api/k6-net-grpc/stream/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
---
title: Stream
excerpt: 'GRPC Streams'
olegbespalov marked this conversation as resolved.
Show resolved Hide resolved
weight: 30
---

# Stream

Using a GRPC client creates a stream. An important note that the client should be already connected (client.connect called) to the server before creating a stream.
olegbespalov marked this conversation as resolved.
Show resolved Hide resolved

| Method | Description |
| ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| [Stream(client, url, [,params])](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/stream) | Using a GRPC client creates a stream. |
olegbespalov marked this conversation as resolved.
Show resolved Hide resolved
| [Stream.write(message)](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/stream/stream-write) | Writes a message to the stream. |
| [Stream.on(event, handler)](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/stream/stream-on) | Set up handler functions for various events on the GRPC stream. |
olegbespalov marked this conversation as resolved.
Show resolved Hide resolved
| [Stream.end()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-net-grpc/stream/stream-end) | Signals to the server that the client has finished sending. |

### Examples

_A k6 script that sends several randomly chosen points from the pre-generated feature database with a variable delay in between. Prints the statistics when they are sent from the server._

{{< code >}}

```javascript
import { Client, Stream } from 'k6/net/grpc';
import { sleep } from 'k6';

const COORD_FACTOR = 1e7;

const GRPC_ADDR = __ENV.GRPC_ADDR || '127.0.0.1:10000';
const GRPC_PROTO_PATH = __ENV.GRPC_PROTO_PATH || '../../grpc_server/route_guide.proto';

const client = new Client();
client.load([], GRPC_PROTO_PATH);

// a sample DB of points
const DB = [
{
location: { latitude: 407838351, longitude: -746143763 },
name: 'Patriots Path, Mendham, NJ 07945, USA',
},
{
location: { latitude: 408122808, longitude: -743999179 },
name: '101 New Jersey 10, Whippany, NJ 07981, USA',
},
{
location: { latitude: 413628156, longitude: -749015468 },
name: 'U.S. 6, Shohola, PA 18458, USA',
},
{
location: { latitude: 419999544, longitude: -740371136 },
name: '5 Conners Road, Kingston, NY 12401, USA',
},
{
location: { latitude: 414008389, longitude: -743951297 },
name: 'Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA',
},
{
location: { latitude: 419611318, longitude: -746524769 },
name: '287 Flugertown Road, Livingston Manor, NY 12758, USA',
},
{
location: { latitude: 406109563, longitude: -742186778 },
name: '4001 Tremley Point Road, Linden, NJ 07036, USA',
},
{
location: { latitude: 416802456, longitude: -742370183 },
name: '352 South Mountain Road, Wallkill, NY 12589, USA',
},
{
location: { latitude: 412950425, longitude: -741077389 },
name: 'Bailey Turn Road, Harriman, NY 10926, USA',
},
{
location: { latitude: 412144655, longitude: -743949739 },
name: '193-199 Wawayanda Road, Hewitt, NJ 07421, USA',
},
];

export default () => {
if (__ITER == 0) {
client.connect(GRPC_ADDR, { plaintext: true });
}

const stream = new Stream(client, 'main.RouteGuide/RecordRoute');

stream.on('data', (stats) => {
console.log('Finished trip with', stats.pointCount, 'points');
console.log('Passed', stats.featureCount, 'features');
console.log('Travelled', stats.distance, 'meters');
console.log('It took', stats.elapsedTime, 'seconds');
});

stream.on('error', (err) => {
console.log('Stream Error: ' + JSON.stringify(err));
});

stream.on('end', () => {
client.close();
console.log('All done');
});

// send 5 random items
for (let i = 0; i < 5; i++) {
const point = DB[Math.floor(Math.random() * DB.length)];
pointSender(stream, point);
}

// close the client stream
stream.end();

sleep(1);
};

const pointSender = (stream, point) => {
console.log(
'Visiting point ' +
point.name +
' ' +
point.location.latitude / COORD_FACTOR +
', ' +
point.location.longitude / COORD_FACTOR
);

// send the location to the server
stream.write(point.location);

sleep(0.5);
};
```

{{< /code >}}

_A k6 script that sends a rectangle message and results (features) are streamed back to the client._

{{< code >}}

```javascript
import { Client, Stream } from 'k6/net/grpc';
import { sleep } from 'k6';

const COORD_FACTOR = 1e7;

const GRPC_ADDR = __ENV.GRPC_ADDR || '127.0.0.1:10000';
const GRPC_PROTO_PATH = __ENV.GRPC_PROTO_PATH || '../../grpc_server/route_guide.proto';

const client = new Client();

client.load([], GRPC_PROTO_PATH);

export default () => {
client.connect(GRPC_ADDR, { plaintext: true });

const stream = new Stream(client, 'main.FeatureExplorer/ListFeatures', null);

stream.on('data', function (feature) {
console.log(
'Found feature called "' +
feature.name +
'" at ' +
feature.location.latitude / COORD_FACTOR +
', ' +
feature.location.longitude / COORD_FACTOR
);
});

stream.on('end', function () {
// The server has finished sending
client.close();
console.log('All done');
});

stream.on('error', function (e) {
// An error has occurred and the stream has been closed.
console.log('Error: ' + JSON.stringify(e));
});

// send a message to the server
stream.write({
lo: {
latitude: 400000000,
longitude: -750000000,
},
hi: {
latitude: 420000000,
longitude: -730000000,
},
});

sleep(0.5);
};
```

{{< /code >}}

The preceding examples use a demo server, which you can run with the following command (Golang should be installed) in [k6 repository's root](https://github.com/grafana/k6):

{{< code >}}

```bash
$ go run -mod=mod examples/grpc_server/*.go
```

{{< /code >}}
Loading
Loading