Planning for Contributing to Telescope
Luigi Zaccagnini
Posted on December 4, 2021
Hello! Welcome to another blog post about contributing to open source. This blog post I am going to discuss the issue I picked to solve and how I am planning to solve it.
Issue at Hand
The issue I decided to choose for this was issue 2444. This issue is about adding CORS to the health checks in Telescope. CORS(cross-origin resource sharing) allows for restricted resources (Stylesheets, scripts, etc.) from one domain to be accessed from another domain. For this issue, when Satellite another Seneca open source project tries to communicate with telescope it causing the CORS issue.
Action Plan
Since this issue requires me to add CORS to satellites health checks, I will have to implement CORS into the src/satellite.js
. Here is a rough idea:
const { createTerminus } = require('@godaddy/terminus');
const { createApp, createRouter } = require('./app');
const redis = require('./redis');
const elastic = require('./elastic');
const logger = require('./logger');
const cors = require('cors');
function createServer(app, credentials) {
// If we're given key/cert credentials, use HTTPS,otherwiseHTTP
app.use(cors());
if (credentials) {
return require('https').createServer(credentials, app);
}
return require('http').createServer(app);
}
class Satellite {
constructor(options = {}) {
// If we're given a healthCheck function, we'll use it with terminus below.
// NOTE: this function should return a Promise.
this.healthCheck =
typeof options.healthCheck === 'function' ? options.healthCheck : () => Promise.resolve();
// If we're given a shutDown function, we'll use it with terminus below.
// NOTE: this function should return a Promise.
this.shutDown =
typeof options.shutDown === 'function' ? options.shutDown : () => Promise.resolve();
// Keep track of credentials if we're passed any
this.credentials = options.credentials;
// Use the router passed to us
this.router = options.router || createRouter();
// Expose the app
this.app = createApp(this.router, options);
}
start(port, callback) {
if (this.server) {
throw new Error('server already started');
}
if (typeof port !== 'number') {
throw new Error(`port number required, got ${port}`);
}
// Expose the server
this.server = createServer(this.app, this.credentials);
// Graceful shutdown and healthcheck
createTerminus(this.server, {
healthChecks: {
'/healthcheck': this.healthCheck,
},
signal: 'SIGINT',
onSignal() {
// Do any async cleanup required to gracefully shutdown. The calls to
// redis/elastic shutDown() will be no-ops if no connections are open.
return Promise.all([this.shutDown(), redis.shutDown(), elastic.shutDown()]).catch((err) =>
logger.error({ err }, 'unexpected error while shutting down')
);
},
logger: (...args) => logger.error(...args),
});
// Start the server
this.server.listen(port, callback);
}
stop(callback) {
const self = this;
function finished() {
self.server = null;
if (typeof callback === 'function') {
callback();
}
}
if (!this.server) {
finished();
return;
}
this.server.close(finished);
}
}
module.exports = Satellite;
Another solution could be to use set headers:
res.writeHead(200, 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET');
This is a plan I hope works but I have much to find out when I start working on the project. Stay tuned for my more in depth blog about working on the issue.
Posted on December 4, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.