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

chore: api and version polish #92

Merged
merged 3 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,12 @@ The run command will expose by default a server on port `8080`.
The server exposes automatically:

- An API, with:
- About info: [http://localhost:8080/api/about](http://localhost:8080/api/about)
- Version info: [http://localhost:8080/api/version](http://localhost:8080/api/version)
- Dump Database: `http://localhost:8080/api/dump/:chainId` e.g. [http://localhost:8080/api/dump/1](http://localhost:8080/api/dump/1)
- Prometheus Metrics: [http://localhost:8080/metrics](http://localhost:8080/metrics)

You can prevent the server from starting by setting the `--enable-api` flag for the `run` command.
You can prevent the server from starting by setting the `--disable-api` flag for the `run` command.

Additionally, you can change the port by setting the flag `--api-port <apiPort>`
Additionally, you can change the default port using the `--api-port <apiPort>` CLI option.

The `/api/about` endpoint, exposes the information in the package.json. This can be helpful to identify the version of the watch tower. Additionally, for environments using docker, the environment variable `DOCKER_IMAGE_TAG` can be used to specify the Docker image tag used.
The `/api/version` endpoint, exposes the information in the package.json. This can be helpful to identify the version of the watch tower. Additionally, for environments using docker, the environment variable `DOCKER_IMAGE_TAG` can be used to specify the Docker image tag used.
36 changes: 23 additions & 13 deletions src/commands/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,23 @@ import { ApiService } from "../utils/api";
*/
export async function run(options: RunOptions) {
const log = getLogger("commands:run");
const { rpc, deploymentBlock, oneShot, enableApi, apiPort } = options;
const { rpc, deploymentBlock, oneShot, disableApi, apiPort } = options;

const api = new ApiService(apiPort);
if (enableApi) {
// Start the API server if it's not disabled
if (!disableApi) {
log.info("Starting Rest API server...");
const api = ApiService.getInstance(apiPort);
await api.start();
}

process.on("unhandledRejection", async (error) => {
log.error("Unhandled promise rejection", error);
await api.stop();
await DBService.getInstance().close();
process.exit(1);
stop(1);
});

process.on("SIGINT", async function () {
log.info("Caught interrupt signal. Closing DB connection.");
await api.stop();
await DBService.getInstance().close();
process.exit(0);
log.info("Caught interrupt signal.");
stop();
});

let exitCode = 0;
Expand Down Expand Up @@ -56,8 +54,20 @@ export async function run(options: RunOptions) {
log.error("Unexpected error thrown when running watchtower", error);
exitCode = 1;
} finally {
await api.stop();
await DBService.getInstance().close();
process.exit(exitCode);
stop(exitCode);
}
}

/**
* Run actions required when stopping the watch-tower from run mode
* @param exitCode Exit code to return to the shell
*/
function stop(exitCode?: number) {
const log = getLogger("commands:stop");
log.info("Stopping Rest API server...");
ApiService.getInstance().stop();
mfw78 marked this conversation as resolved.
Show resolved Hide resolved
log.info("Closing database...");
DBService.getInstance().close();
log.info("Exiting watchtower...");
process.exit(exitCode || 0);
}
8 changes: 3 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import { program, Option } from "@commander-js/extra-typings";
import { ReplayTxOptions } from "./types";
import { dumpDb, replayBlock, replayTx, run } from "./commands";
import { initLogging } from "./utils";
import { version, description } from "../package.json";

const logLevelOption = new Option("--log-level <logLevel>", "Log level")
.default("INFO")
.env("LOG_LEVEL");

async function main() {
program
.name("watchtower")
.description("Monitoring Composable CoW smart orders on the blockchain 🐮")
.version("0.2.0");
program.name("watchtower").description(description).version(version);
mfw78 marked this conversation as resolved.
Show resolved Hide resolved

program
.command("run")
Expand All @@ -38,7 +36,7 @@ async function main() {
.conflicts(["slackWebhook"])
.default(false)
)
.option("--enable-api", "Enable the REST API", true)
.option("--disable-api", "Disable the REST API", false)
.option("--api-port <apiPort>", "Port for the REST API", "8080")
.option("--slack-webhook <slackWebhook>", "Slack webhook URL")
.option("--one-shot", "Run the watchtower once and exit", false)
Expand Down
2 changes: 1 addition & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface RunOptions extends WatchtowerOptions {
silent: boolean;
slackWebhook?: string;
oneShot: boolean;
enableApi: boolean;
disableApi: boolean;
apiPort: number;
mfw78 marked this conversation as resolved.
Show resolved Hide resolved
}

Expand Down
17 changes: 11 additions & 6 deletions src/utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ export class ApiService {
protected app: Express;
protected server: Server | null = null;

constructor(port: number) {
this.port = port;
private static _instance: ApiService | undefined;

protected constructor(port?: number) {
this.port = port || 8080;
this.app = express();
this.bootstrap();
}
Expand All @@ -37,8 +39,11 @@ export class ApiService {
});
}

get getApp(): Express {
return this.app;
public static getInstance(port?: number): ApiService {
if (!ApiService._instance) {
ApiService._instance = new ApiService(port);
}
return ApiService._instance;
}

async start(): Promise<Server> {
Expand All @@ -50,7 +55,7 @@ export class ApiService {
}
this.server = this.app.listen(this.port, () => {
log.info(
`Starting Rest API server on port ${this.port}. See http://localhost:8080/api/about`
`Rest API server is running on port ${this.port}. See http://localhost:${this.port}/api/version`
mfw78 marked this conversation as resolved.
Show resolved Hide resolved
);
});

Expand Down Expand Up @@ -96,7 +101,7 @@ const dumpRoute = (router: Router) => {
};

const aboutRoute = (router: Router) => {
router.get("/about", async (req: Request, res: Response) => {
router.get("/version", async (req: Request, res: Response) => {
res.setHeader("Content-Type", "application/json");
res.send({
version,
Expand Down