Skip to content

Commit b48d8e8

Browse files
authored
Merge pull request #30 from omnia-network/release-1.4.0
chore: release v1.4.0
2 parents 366243f + 1c4e8aa commit b48d8e8

File tree

5 files changed

+75
-31
lines changed

5 files changed

+75
-31
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# IC WebSocket Gateway
22

3+
[![GitHub Release](https://img.shields.io/github/v/release/omnia-network/ic-websocket-gateway)](https://github.com/omnia-network/ic-websocket-gateway/releases)
4+
[![GitHub License](https://img.shields.io/github/license/omnia-network/ic-websocket-gateway)](https://github.com/omnia-network/ic-websocket-gateway/blob/main/LICENSE)
5+
[![Docker Pulls](https://img.shields.io/docker/pulls/omniadevs/ic-websocket-gateway?logo=docker)](https://hub.docker.com/r/omniadevs/ic-websocket-gateway)
6+
37
WebSockets enable web applications to maintain a full-duplex connection between the backend and the frontend. This allows for many different use-cases, such as notifications, dynamic content updates (e.g., showing new comments/likes on a post), collaborative editing, etc.
48

59
At the moment, the Internet Computer does not natively support WebSocket connections and developers need to resort to work-arounds in the frontend to enable a similar functionality. This results in a poor developer experience and an overload of the backend canister.
@@ -8,12 +12,10 @@ This repository contains the implementation of a WebSocket Gateway enabling clie
812

913
# Running the WS Gateway
1014

11-
## Prerequisites
15+
## Standalone
1216

1317
Make sure you have the **Rust toolchain** installed. You can find instructions [here](https://www.rust-lang.org/tools/install).
1418

15-
## Standalone
16-
1719
1. Run the gateway:
1820

1921
In **debug** mode:
@@ -39,25 +41,57 @@ Make sure you have the **Rust toolchain** installed. You can find instructions [
3941
2024-03-14T11:19:33.650018Z INFO ic_websocket_gateway::manager: Start accepting incoming connections
4042
```
4143

42-
### Options available
44+
### Arguments available
4345

4446
There are some command line arguments that you can set when running the gateway:
4547
| Argument | Description | Default |
4648
| --- | --- | --- |
4749
| `--gateway-address` | The **IP:port** on which the gateway will listen for incoming connections. | `0.0.0.0:8080` |
4850
| `--ic-network-url` | The URL of the IC network to which the gateway will connect. | `http://127.0.0.1:4943` |
4951
| `--polling-interval` | The interval (in **milliseconds**) at which the gateway will poll the canisters for new messages. | `100` |
52+
| `--prometheus-endpoint` | The **IP:port** on which the gateway will expose Prometheus metrics. | `0.0.0.0:9090` |
5053
| `--tls-certificate-pem-path` | The path to the TLS certificate file. See [Obtain a TLS certificate](#obtain-a-tls-certificate) for more details. | _empty_ |
5154
| `--tls-certificate-key-pem-path` | The path to the TLS private key file. See [Obtain a TLS certificate](#obtain-a-tls-certificate) for more details. | _empty_ |
5255
| `--opentelemetry-collector-endpoint` | OpenTelemetry collector endpoint. See [Tracing telemetry](#tracing-telemetry) for more details. | _empty_ |
5356

5457
## Docker
5558

56-
A [Dockerfile](./Dockerfile) is provided, together with the files [docker-compose.yml](./docker-compose.yml), [docker-compose-local.yml](./docker-compose-local.yml) and [docker-compose-prod.yml](./docker-compose-prod.yml) to run the gateway according to the needs. Make sure you have [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/) installed.
59+
Make sure you have [Docker](https://docs.docker.com/get-docker/) installed.
60+
61+
A [Dockerfile](./Dockerfile) is provided. To build the image, run:
62+
63+
```bash
64+
docker build -t ic-websocket-gateway .
65+
```
66+
67+
Then, run the gateway with the following command:
68+
69+
```bash
70+
docker run -p 8080:8080 ic-websocket-gateway
71+
```
72+
73+
A Docker image is also available at [omniadevs/ic-websocket-gateway](https://hub.docker.com/r/omniadevs/ic-websocket-gateway), that you can run with the following command:
5774

58-
A Docker image is also available at [omniadevs/ic-websocket-gateway](https://hub.docker.com/r/omniadevs/ic-websocket-gateway). This is the image used in the [docker-compose.yml](./docker-compose.yml) file.
75+
```bash
76+
docker run -p 8080:8080 omniadevs/ic-websocket-gateway
77+
```
78+
79+
Have a look at the [Arguments available](#arguments-available) to configure the gateway for your needs.
80+
81+
## Docker Compose
82+
83+
Make sure you have [Docker Compose](https://docs.docker.com/compose/install/) installed.
84+
85+
The following compose files are available:
86+
87+
- [docker-compose.yml](./docker-compose.yml)
88+
- [docker-compose-local.yml](./docker-compose-local.yml)
89+
- [docker-compose-prod.yml](./docker-compose-prod.yml)
90+
91+
The following sections describe how to use the different compose files to run the gateway with Docker Compose.
5992

6093
### Local
94+
6195
To run the gateway in a local environment with Docker Compose, follow these steps:
6296
1. To run all the required local structure you can execute the [start_local_docker_environment.sh](./scripts/start_local_docker_environment.sh) with the command:
6397

@@ -71,18 +105,24 @@ To run the gateway in a local environment with Docker Compose, follow these step
71105
docker compose -f docker-compose.yml -f docker-compose-local.yml --env-file .env.local up -d --build
72106
```
73107

74-
2. To stop and clean all the local environment a bash script [stop_local_docker_environment.sh](./scripts/stop_local_docker_environment.sh) is provided. You can execute it with the command:
108+
2. To stop and clean all the local environment, the bash script [stop_local_docker_environment.sh](./scripts/stop_local_docker_environment.sh) is provided. You can execute it with the command:
75109

76110
```
77111
./scripts/stop_local_docker_environment.sh
78112
```
79113

80-
3. The Gateway will print its principal in the container logs, just as explained above.
81-
4. If you want to verify that all is started correctly a bash script [run_test_canister.sh](./scripts/run_test_canister.sh) is provided. This assumes that the gateway is already running.
114+
3. The Gateway will print its principal in the container logs, just as explained in the [Standalone](#standalone) section.
115+
4. If you want to verify that everything started correctly, the bash script [run_test_canister.sh](./scripts/run_test_canister.sh) is provided. This script assumes that the gateway is already running and reachable locally. You can execute it with the command:
116+
117+
```
118+
./scripts/run_test_canister.sh
119+
```
82120

83121
### Production
84122

85-
To run the gateway in a prod environment with Docker Compose, follow these steps:
123+
This configuration uses the [omniadevs/ic-websocket-gateway](https://hub.docker.com/r/omniadevs/ic-websocket-gateway) image.
124+
125+
To run the gateway in a production environment with Docker Compose, follow these steps:
86126
1. Set the environment variables:
87127

88128
```
@@ -91,26 +131,26 @@ To run the gateway in a prod environment with Docker Compose, follow these steps
91131

92132
2. To run the [docker-compose-prod.yml](./docker-compose-prod.yml) file you need a public domain (that you will put in the `DOMAIN_NAME` environment variable) and a TLS certificate for that domain (because it is configured to make the gateway run with TLS enabled). See [Obtain a TLS certificate](#obtain-a-tls-certificate) for more details.
93133
3. Open the `443` port (or the port that you set in the `LISTEN_PORT` environment variable) on your server and make it reachable from the Internet.
94-
4. To run all the required production structure you can execute the [start_prod_docker_environment.sh](./scripts/start_prod_docker_environment.sh) with the command:
134+
4. To run all the required production containers you can execute the [start_prod_docker_environment.sh](./scripts/start_prod_docker_environment.sh) with the command:
95135

96136
```
97137
./scripts/start_prod_docker_environment.sh
98138
```
99139

100-
This script firstly generated the `telemetry/prometheus/prometheus-prod.yml` config file starting from the `telemetry/prometheus/prometheus-template.yml` (step required to perform the variable substitution) and then simply run the gateway with the following command:
140+
This script first generates the `telemetry/prometheus/prometheus-prod.yml` config file from the `telemetry/prometheus/prometheus-template.yml` template (step required to perform the environment variables substitution) and then runs the gateway with the following command:
101141

102142
```
103-
docker compose -f docker-compose.yml -f docker-compose-prod.yml --env-file .env up -d --build
143+
docker compose -f docker-compose.yml -f docker-compose-prod.yml --env-file .env up -d
104144
```
105145

106-
5. To stop and clean all the local environment a bash script [stop_prod_docker_environment.sh](./scripts/stop_prod_docker_environment.sh) is provided. You can execute it with the command:
146+
5. To stop and clean the containers, the bash script [stop_prod_docker_environment.sh](./scripts/stop_prod_docker_environment.sh) is provided. You can execute it with the command:
107147

108148
```
109149
./scripts/stop_prod_docker_environment.sh
110150
```
111-
6. The Gateway will print its principal in the container logs, just as explained above.
151+
6. The Gateway will print its principal in the container logs, just as explained in the [Standalone](#standalone) section.
112152

113-
### Obtain a TLS certificate
153+
#### Obtain a TLS certificate
114154

115155
1. Buy a domain name and point it to the server where you are running the gateway.
116156
2. Make sure the `.env` file is configured with the correct domain name, see above.

src/ic-websocket-gateway/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ic_websocket_gateway"
3-
version = "1.3.3"
3+
version = "1.4.0"
44
edition.workspace = true
55
rust-version.workspace = true
66
repository.workspace = true

src/ic-websocket-gateway/src/gateway_metrics.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
use std::error::Error;
2-
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
3-
use std::time::Duration;
41
use metrics::{describe_gauge, describe_histogram, gauge};
52
use metrics_exporter_prometheus::PrometheusBuilder;
6-
use metrics_util::{MetricKindMask};
3+
use metrics_util::MetricKindMask;
4+
use std::error::Error;
5+
use std::net::SocketAddr;
6+
use std::str::FromStr;
7+
use std::time::Duration;
78

8-
pub fn init_metrics(port: Option<u16>) -> Result<(), Box<dyn Error>> {
9-
let builder = PrometheusBuilder::new()
10-
.with_http_listener(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), port.unwrap_or(9000)));
9+
pub fn init_metrics(address: &str) -> Result<(), Box<dyn Error>> {
10+
let builder = PrometheusBuilder::new().with_http_listener(SocketAddr::from_str(address)?);
1111

1212
// Set the idle timeout for counters and histograms to 30 seconds then the metrics are removed from the registry
1313
builder
14-
.idle_timeout(
15-
MetricKindMask::ALL,
16-
Some(Duration::from_secs(30)),
17-
)
14+
.idle_timeout(MetricKindMask::ALL, Some(Duration::from_secs(30)))
1815
.install()
1916
.expect("failed to install Prometheus recorder");
2017

21-
describe_gauge!("clients_connected", "The number of clients currently connected");
18+
describe_gauge!(
19+
"clients_connected",
20+
"The number of clients currently connected"
21+
);
2222
describe_gauge!("active_pollers", "The number of pollers currently active");
2323
describe_histogram!(
2424
"connection_duration",

src/ic-websocket-gateway/src/main.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ struct DeploymentInfo {
3636
/// Time interval (in milliseconds) at which the canisters are polled.
3737
polling_interval: u64,
3838

39+
#[structopt(long, default_value = "0.0.0.0:9000")]
40+
/// Prometheus endpoint on which the metrics are exposed.
41+
prometheus_endpoint: String,
42+
3943
#[structopt(long)]
4044
tls_certificate_pem_path: Option<String>,
4145

@@ -79,7 +83,7 @@ async fn main() -> Result<(), String> {
7983
)
8084
.expect("could not init tracing");
8185

82-
init_metrics(None).expect("could not init metrics");
86+
init_metrics(&deployment_info.prometheus_endpoint).expect("could not init metrics");
8387

8488
// must be printed after initializing tracing to ensure that the info are captured
8589
info!("Deployment info: {:?}", deployment_info);

0 commit comments

Comments
 (0)