diff --git a/README.md b/README.md index 3ecbede2f8998e996a79944d79b7b91f2084af97..bdb129538dc85f162143830d03da257136e2d460 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,34 @@ [](https://gitlab.inria.fr/concordant/software/c-server/-/commits/master) Server code for the C-Labbook demo. +The first version of C-Service API. -Install dependencies with: +## Getting started + +0.**Requirements** + +For the next steps, you will need the following software: + +- Make sure you have the latest version of Node.js: [see official installation guide](https://nodejs.org/en/download/); +- The project uses Git to download some required dependencies: [follow the official install guide](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +- C-Server runs on top of CouchDB, [see CouchDB's installation guide](https://docs.couchdb.org/en/stable/install/index.html) + +In addition, you will need to enable CORS in CouchDB + +```shell +npx add-cors-to-couchdb +``` + +1.**Install Project dependencies** + +Go to project root directory and: ```bash npm install ``` +2.**Start C-Server** + Set database name and credentials and run server: ```bash @@ -19,9 +40,10 @@ export DBNAME=my-database COUCHDB_USER=my-user COUCHDB_PASSWORD=my-passwd npm start ``` -Need to start a CouchDB server beforehand. Can customize the database url with the environment variable COUCHDB_URL. You might need to change the binding address in CouchDB admin panel to allow peers to connect to the database. +**Note:** Need to start a CouchDB server beforehand. Can customize the database URL with the environment variable COUCHDB_URL. +You might need to change the binding address in the CouchDB admin panel to allow peers to connect to the database. -Run tests with: +You can also run tests using: ```bash npm test diff --git a/package-lock.json b/package-lock.json index 90328b8bc13da886564e1c53fb92d705bb49f1f2..a205edbe6297192b90803e78d51ccb52546d2ed8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "c-server", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4402daef2544295c3461a0560cf6b799c7ac4105..af899a3462b54a0ad5bb57752711a4b241becc7a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "c-server", - "version": "1.1.0", - "description": "Storage backend designed for the C-Labbook demo", + "version": "1.1.1", + "description": "Server backend for Concordant P2P collaborative apps", "main": "./dist/main.js", "types": "./dist/main.d.ts", "files": [ diff --git a/src/server.ts b/src/server.ts index 5c2ba8cc2d57cac803a165007b0b6a0aa23c4f0f..051834956997221c6a930beae915a621ab8d2740 100644 --- a/src/server.ts +++ b/src/server.ts @@ -186,16 +186,48 @@ server.applyMiddleware({ app }); app.listen({ port: 4000 }); +/** + * DBNAME is required env arg for the application, exit if unset + */ if (!dbName) { console.error("Please set DBNAME environment variable"); process.exit(1); } +/** + * Creates a new Database, used when DBNAME doesn't exist + * + * In case of failure, the server will exist with error + * TODO: init DB with defaults + * + * @param appDB CouchDB DatabaseScope instance where to create the new DB + * @param dbName new DB name + */ +function createDB(appDB: Nano.DatabaseScope, dbName: string) { + console.warn("[SERVER] Creating DB:" + dbName); + appDB.create(dbName).catch((error) => { + console.error(`[SERVER][ERROR] Failed creating database ${dbName}`); + console.error(error); + process.exit(1); + }); +} + +/** + * Poll appDB waiting for connection ack + * + * If DBNAME doesn't exist, it will be created + * + * @param timeout polling sleep duration, multiplied by 2 at each retry + */ const connectDB = (timeout = 1000) => appDB.info().catch((error) => { const retryIn = Math.min(timeout * 2, maxRetryTimeout); setTimeout(() => connectDB(retryIn), retryIn); console.warn(error, `retry in ${retryIn}`); + // If DB doesn't exist, create it before first retry + if (error && error.error === "not_found" && timeout <= 1000) { + createDB(client.db, dbName); + } }); const client = Nano({ url: dbUrl, requestDefaults: { jar: true } });