Skip to content

Commit d2f1732

Browse files
authored
feat: Include version in startup message (cube-js#615) Thanks to jcw-!
* feat: Include version in startup message * Add version to startup message * Add version to CubejsServer * Add version to CubejsServerCore * Make version available in return of listen * Use version returned from listen * Make version an immutable static method * Update docs with how to use version * Update doc examples to log version * Update examples to log version * Update guides to log version * Update TypeScript type to include version
1 parent 23da279 commit d2f1732

File tree

23 files changed

+156
-132
lines changed

23 files changed

+156
-132
lines changed

β€Ždocs/Cube.js-Backend/@cubejs-backend-server-core.md

+12-3
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,6 @@ CubejsServerCore.create({
195195
})
196196
```
197197

198-
199198
### contextToAppId
200199

201200
It is a [Multitenancy Setup](multitenancy-setup) option.
@@ -319,7 +318,7 @@ It is usually used in [Multitenancy Setup](multitenancy-setup).
319318

320319
### schemaVersion
321320

322-
Schema version can be used to tell Cube.js schema should be recompiled in case schema code depends on dynamic definitions fetched from some external database or API.
321+
Schema version can be used to tell Cube.js schema should be recompiled in case schema code depends on dynamic definitions fetched from some external database or API.
323322
This method is called on each request however `RequestContext` parameter is reused per application id returned by [contextToAppId](#options-reference-context-to-app-id).
324323
If returned string has been changed, schema will be recompiled.
325324
It can be used in both multitenant and single tenant environments.
@@ -369,7 +368,7 @@ Providing `updateCompilerCacheKeepAlive: true` keeps frequently used schemas in
369368

370369
### allowUngroupedWithoutPrimaryKey
371370

372-
Providing `allowUngroupedWithoutPrimaryKey: true` disables primary key inclusion check for `ungrouped` queries.
371+
Providing `allowUngroupedWithoutPrimaryKey: true` disables primary key inclusion check for `ungrouped` queries.
373372

374373
### telemetry
375374

@@ -455,3 +454,13 @@ CubejsServerCore.create({
455454
repositoryFactory: ({authInfo}) => new ApiFileRepository()
456455
});
457456
```
457+
458+
## Version
459+
460+
`CubejsServerCore.version` is a method that returns the semantic package version of `@cubejs-backend/server`.
461+
462+
```javascript
463+
const CubejsServerCore = require('@cubejs-backend/server-core');
464+
465+
console.log(CubejsServerCore.version());
466+
```

β€Ždocs/Cube.js-Backend/@cubejs-backend-server.md

+17-5
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,37 @@ Creates an instance of `CubejsServer`.
1818

1919
You can set server port using `PORT` environment variable. Default port is `4000`.
2020

21-
### Example
21+
#### Example
2222

2323
```javascript
2424
const CubejsServer = require('@cubejs-backend/server');
2525

2626
const server = new CubejsServer();
2727

28-
server.listen().then(({ port }) => {
29-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
28+
server.listen().then(({ version, port }) => {
29+
console.log(`πŸš€ Cube.js server (${version}) is listening on ${port}`);
3030
});
3131
```
3232

33+
### CubejsServer.version()
34+
35+
`CubejsServer.version` is a method that returns the semantic package version of `@cubejs-backend/server`.
36+
37+
```javascript
38+
const CubejsServer = require('@cubejs-backend/server');
39+
40+
console.log(CubejsServer.version());
41+
```
42+
3343
### this.listen([options])
3444

3545
Instantiates the Express.js App to listen to the specified `PORT`. Returns a promise that resolves with the following members:
3646

3747
* `port {number}` The port at which CubejsServer is listening for insecure connections for redirection to HTTPS, as specified by the environment variable `PORT`. Defaults to 4000.
48+
* `tlsPort {number}` If TLS is enabled, the port at which CubejsServer is listening for secure connections, as specified by the environment variable `TLS_PORT`. Defaults to 4433.
3849
* `app {Express.Application}` The express App powering CubejsServer
3950
* `server {http.Server}` The `http` Server instance. If TLS is enabled, returns a `https.Server` instance instead.
51+
* `version {string}` The semantic package version of `@cubejs-backend/server`
4052

4153
Cube.js can also support TLS encryption. See the [Security page on how to enable tls](security#enabling-tls) for more information.
4254

@@ -50,8 +62,8 @@ const { createTerminus } = require('@godaddy/terminus');
5062

5163
const cubejsServer = new CubejsServer();
5264

53-
cubejsServer.listen().then(({ port, server }) => {
54-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
65+
cubejsServer.listen().then(({ version, port, server }) => {
66+
console.log(`πŸš€ Cube.js server (${version}) is listening on ${port}`);
5567

5668
createTerminus(server, {
5769
healthChecks: {

β€Ždocs/Cube.js-Backend/Caching.md

+14-14
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ The second in-database level is called **pre-aggregations** and requires explici
1919
Cube.js caches the results of executed queries using in-memory cache. The cache
2020
key is generated SQL with any existing query dependent pre-aggregations.
2121

22-
Upon incoming request Cube.js first checks the cache using this key.
22+
Upon incoming request Cube.js first checks the cache using this key.
2323
If nothing is found it executes the query in database, returns result back alongside writing to the cache.
2424
Since 0.15.0 in case there's an existing value in cache it will be returned only if `refreshKey` value for query isn't changed.
2525
Otherwise [query renewal](#in-memory-cache-force-query-renewal) will be performed.
@@ -33,12 +33,12 @@ So, Cube.js defines a `refreshKey` for each cube. [refreshKeys](cube#parameters-
3333

3434
__Note__: Cube.js *also caches* the results of `refreshKeys` for a fixed time interval in order to avoid issuing them too often. If you need Cube.js to immediately respond to changes in data, see the [Force Query Renewal](#in-memory-cache-force-query-renewal) section.
3535

36-
When a query's result needs to be refreshed, Cube.js will re-execute the query in the foreground and repopulate the cache.
37-
This means that cached results may still be served to users requesting them while `refreshKey` values aren't changed from Cube.js perspective.
36+
When a query's result needs to be refreshed, Cube.js will re-execute the query in the foreground and repopulate the cache.
37+
This means that cached results may still be served to users requesting them while `refreshKey` values aren't changed from Cube.js perspective.
3838
The cache entry will be refreshed in the foreground if one of the two following conditions is met:
3939

4040
- Query cache entry is expired. The default expiration time is 6 hours for cubes with default `refreshKey` and 24 hours where it was set.
41-
- The result of the `refreshKey` SQL query is different from the previous one. At this stage `refreshKey` won't be refreshed in foreground if it's available in cache.
41+
- The result of the `refreshKey` SQL query is different from the previous one. At this stage `refreshKey` won't be refreshed in foreground if it's available in cache.
4242

4343
### Refresh Key Implementation
4444

@@ -57,8 +57,8 @@ You can set up a custom refresh check SQL by changing [refreshKey](cube#paramete
5757

5858
In these instances, Cube.js needs a query crafted to detect updates to the rows that power the cubes. Often, a `MAX(updated_at_timestamp)` for OLTP data will accomplish this, or examining a metadata table for whatever system is managing the data to see when it last ran.
5959

60-
Note that the result of `refreshKey` query itself is cached for 10 seconds for RDBMS backends and for 2 minutes for big data backends by default.
61-
You can change it by passing [refreshKey every](cube#parameters-refresh-key) parameter.
60+
Note that the result of `refreshKey` query itself is cached for 10 seconds for RDBMS backends and for 2 minutes for big data backends by default.
61+
You can change it by passing [refreshKey every](cube#parameters-refresh-key) parameter.
6262
This cache is useful so that Cube.js can build query result cache keys without issuing database queries and respond to cached requests very quickly.
6363

6464
### Force Query Renewal
@@ -75,8 +75,8 @@ If you need to force a specific query to load fresh data from the database (if i
7575

7676
The `renewQuery` option applies to the `refreshKey` caching system mentioned above, *not* the actual query result cache. If `renewQuery` is passed, Cube.js will always re-execute the `refreshKey` query, skipping that layer of caching, but, if the result of the `refreshKey` query is the same as the last time it ran, that indicates any current query result cache entries are valid, and they will be served. This means that cached data may still be served by Cube.js even if `renewQuery` is passed. This is a good thing: if the underlying data hasn't changed, the expensive query doesn't need to be re-run, and the database doesn't have to work as hard. This does mean that the `refreshKey` SQL must accurately report data freshness for the `renewQuery` to actually work and renew the query.
7777

78-
For situations like real-time analytics or responding to live user changes to underlying data, the `refreshKey` query cache can prevent fresh data from showing up immediately.
79-
For these situations, you can mostly disable the `refreshKey` cache by setting the [refreshKey every](cube#parameters-refresh-key) parameter to something very low, like `1 second`.
78+
For situations like real-time analytics or responding to live user changes to underlying data, the `refreshKey` query cache can prevent fresh data from showing up immediately.
79+
For these situations, you can mostly disable the `refreshKey` cache by setting the [refreshKey every](cube#parameters-refresh-key) parameter to something very low, like `1 second`.
8080
This means Cube.js will always check the data freshness before executing a query, and notice any changed data underneath.
8181

8282
## Pre-Aggregations
@@ -100,7 +100,7 @@ reference.](pre-aggregations)
100100
```javascript
101101
cube(`Orders`, {
102102
// ...
103-
103+
104104
preAggregations: {
105105
amountByCreated: {
106106
type: `rollup`,
@@ -113,7 +113,7 @@ cube(`Orders`, {
113113
```
114114

115115
### Refresh Strategy
116-
116+
117117
Refresh strategy can be customized by setting the [refreshKey](pre-aggregations#refresh-key) property for the pre-aggregation.
118118

119119
The default value of the `refreshKey` is the same as for cube that defines pre-aggregation.
@@ -123,7 +123,7 @@ It can be redefined either by providing SQL
123123
```javascript
124124
cube(`Orders`, {
125125
// ...
126-
126+
127127
preAggregations: {
128128
amountByCreated: {
129129
type: `rollup`,
@@ -143,7 +143,7 @@ or by providing refresh time interval
143143
```javascript
144144
cube(`Orders`, {
145145
// ...
146-
146+
147147
preAggregations: {
148148
amountByCreated: {
149149
type: `rollup`,
@@ -183,8 +183,8 @@ const server = new CubejsServer();
183183

184184
setInterval(() => server.runScheduledRefresh(), 5000);
185185

186-
server.listen().then(({ port }) => {
187-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
186+
server.listen().then(({ version, port }) => {
187+
console.log(`πŸš€ Cube.js server (${version}) is listening on ${port}`);
188188
}).catch(e => {
189189
console.error('Fatal error during server start: ');
190190
console.error(e.stack || e);

β€Ždocs/Cube.js-Backend/Deployment.md

+9-11
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ Below you can find guides for popular deployment environments:
1515

1616
## Production Mode
1717

18-
When running Cube.js Backend in production make sure `NODE_ENV` is set to `production`.
18+
When running Cube.js Backend in production make sure `NODE_ENV` is set to `production`.
1919
Such platforms, such as Heroku, do it by default.
2020
In this mode Cube.js unsecured development server and Playground will be disabled by default because there's a security risk serving those in production environments.
21-
Production Cube.js servers can be accessed only with [REST API](rest-api) and Cube.js frontend libraries.
21+
Production Cube.js servers can be accessed only with [REST API](rest-api) and Cube.js frontend libraries.
2222

2323
### Redis
2424

25-
Also, Cube.js requires [Redis](https://redis.io/), in-memory data structure store, to run in production.
26-
It uses Redis for query caching and queue.
27-
Set `REDIS_URL` environment variable to provide Cube.js with Redis connection. In case your Redis instance has password, please set password via `REDIS_PASSWORD` environment variable.
25+
Also, Cube.js requires [Redis](https://redis.io/), in-memory data structure store, to run in production.
26+
It uses Redis for query caching and queue.
27+
Set `REDIS_URL` environment variable to provide Cube.js with Redis connection. In case your Redis instance has password, please set password via `REDIS_PASSWORD` environment variable.
2828
Make sure, your Redis allows at least 15 concurrent connections.
2929
Set `REDIS_TLS` env variable to `true` if you want to enable secure connection.
3030

@@ -65,7 +65,7 @@ app.listen(port, (err) => {
6565
console.error('Fatal error during server start: ');
6666
console.error(e.stack || e);
6767
}
68-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
68+
console.log(`πŸš€ Cube.js server (${CubejsServerCore.version()}) is listening on ${port}`);
6969
});
7070
```
7171

@@ -143,7 +143,7 @@ server.listen(port, (err) => {
143143
console.error('Fatal error during server start: ');
144144
console.error(e.stack || e);
145145
}
146-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
146+
console.log(`πŸš€ Cube.js server (${CubejsServerCore.version()}) is listening on ${port}`);
147147
});
148148
```
149149

@@ -370,7 +370,7 @@ $ docker stop cubejs-docker-demo
370370

371371
## Docker Compose
372372

373-
To run the server in docker-compose we need to add a redis server and a .env file to include the environment variables needed to connect to the database, the secret api secret and redis hostname.
373+
To run the server in docker-compose we need to add a redis server and a .env file to include the environment variables needed to connect to the database, the secret api secret and redis hostname.
374374

375375
Example .env file
376376

@@ -411,7 +411,7 @@ Build the containers
411411
$ docker-compose build
412412
```
413413

414-
### Start/Stop the containers
414+
### Start/Stop the containers
415415

416416
```bash
417417
$ docker-compose up
@@ -420,5 +420,3 @@ $ docker-compose up
420420
```bash
421421
$ docker-compose stop
422422
```
423-
424-

β€Ždocs/Cube.js-Backend/Multitenancy-Setup.md

+20-20
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Cube.js supports multitenancy out of the box, both on database and data schema l
99
Multiple drivers are also supported, meaning that you can have one customer’s data in MongoDB and others in Postgres with one Cube.js instance.
1010

1111
There are 7 [configuration options](@cubejs-backend-server-core#options-reference) you can leverage to make your multitenancy setup.
12-
You can use all of them or just a couple, depending on your specific case.
12+
You can use all of them or just a couple, depending on your specific case.
1313
The options are:
1414

1515
- `contextToAppId`
@@ -62,20 +62,20 @@ const server = new CubejsServer({
6262
} else if (dataSource === 'googleAnalytics') {
6363
return new BigQueryDriver();
6464
} else if (dataSource === 'financials'){
65-
return new PostgresDriver({
66-
database: 'financials',
67-
host: 'financials-db.acme.com',
68-
user: process.env.FINANCIALS_DB_USER,
69-
password: process.env.FINANCIALS_DB_PASS
65+
return new PostgresDriver({
66+
database: 'financials',
67+
host: 'financials-db.acme.com',
68+
user: process.env.FINANCIALS_DB_USER,
69+
password: process.env.FINANCIALS_DB_PASS
7070
});
7171
} else {
7272
return new PostgresDriver();
7373
}
7474
}
7575
});
7676

77-
server.listen().then(({ port }) => {
78-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
77+
server.listen().then(({ version, port }) => {
78+
console.log(`πŸš€ Cube.js server (${version}) is listening on ${port}`);
7979
});
8080
```
8181

@@ -103,8 +103,8 @@ const server = new CubejsServer({
103103
}
104104
});
105105

106-
server.listen().then(({ port }) => {
107-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
106+
server.listen().then(({ version, port }) => {
107+
console.log(`πŸš€ Cube.js server (${version}) is listening on ${port}`);
108108
});
109109
```
110110

@@ -142,8 +142,8 @@ const server = new CubejsServer({
142142
contextToAppId: ({ authInfo }) => `CUBEJS_APP_${authInfo.appId}_${authInfo.userId}`
143143
});
144144

145-
server.listen().then(({ port }) => {
146-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
145+
server.listen().then(({ version, port }) => {
146+
console.log(`πŸš€ Cube.js server (${version}) is listening on ${port}`);
147147
});
148148
```
149149

@@ -163,8 +163,8 @@ const server = new CubejsServer({
163163
})
164164
});
165165

166-
server.listen().then(({ port }) => {
167-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
166+
server.listen().then(({ version, port }) => {
167+
console.log(`πŸš€ Cube.js server (${version}) is listening on ${port}`);
168168
});
169169
```
170170

@@ -182,8 +182,8 @@ const server = new CubejsServer({
182182
preAggregationsSchema: ({ authInfo }) => `pre_aggregations_${authInfo.userId}`
183183
});
184184

185-
server.listen().then(({ port }) => {
186-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
185+
server.listen().then(({ version, port }) => {
186+
console.log(`πŸš€ Cube.js server (${version}) is listening on ${port}`);
187187
});
188188
```
189189

@@ -224,8 +224,8 @@ const server = new CubejsServer({
224224
}
225225
});
226226

227-
server.listen().then(({ port }) => {
228-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
227+
server.listen().then(({ version, port }) => {
228+
console.log(`πŸš€ Cube.js server (${version}) is listening on ${port}`);
229229
});
230230
```
231231

@@ -265,8 +265,8 @@ const server = new CubejsServer({
265265
repositoryFactory: ({ authInfo }) => new FileRepository(`schema/${authInfo.appId}`)
266266
});
267267

268-
server.listen().then(({ port }) => {
269-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
268+
server.listen().then(({ version, port }) => {
269+
console.log(`πŸš€ Cube.js server (${version}) is listening on ${port}`);
270270
});
271271
```
272272

β€Ždocs/Cube.js-Backend/Security.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ var tlsOptions = {
175175
176176
const cubejsServer = new CubejsServer();
177177
178-
cubejsServer.listen(tlsOptions).then(({ tlsPort }) => {
179-
console.log(`πŸš€ Cube.js server is listening securely on ${tlsPort}`);
178+
cubejsServer.listen(tlsOptions).then(({ version, tlsPort }) => {
179+
console.log(`πŸš€ Cube.js server (${version}) is listening securely on ${tlsPort}`);
180180
});
181181
```
182182
@@ -209,10 +209,10 @@ async function main() {
209209
const certOptions = { days: 2, selfSigned: true };
210210
const tlsOptions = await createCertificate(certOptions);
211211
212-
const ({ tlsPort, server }) = await cubejsServer.listen(tlsOptions);
213-
214-
console.log(`πŸš€ Cube.js server is listening securely on ${tlsPort}`);
215-
212+
const ({ version, tlsPort, server }) = await cubejsServer.listen(tlsOptions);
213+
214+
console.log(`πŸš€ Cube.js server (${version}) is listening securely on ${tlsPort}`);
215+
216216
scheduleCertificateRenewal(server, certOptions, (err, result) => {
217217
if (err !== null) {
218218
console.error(

β€Žexamples/d3-dashboard/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const http = require("http");
66
const serveStatic = require('serve-static');
77
require('dotenv').config();
88

9-
var app = express();
9+
const app = express();
1010
app.use(bodyParser.json({ limit: "50mb" }));
1111
app.use(require('cors')());
1212

@@ -26,5 +26,5 @@ const port = process.env.PORT || 4000;
2626
const server = http.createServer({}, app);
2727

2828
server.listen(port, () => {
29-
console.log(`πŸš€ Cube.js server is listening on ${port}`);
29+
console.log(`πŸš€ Cube.js server (${CubejsServerCore.version()}) is listening on ${port}`);
3030
});

0 commit comments

Comments
Β (0)