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

feature: allow final shutdown notification #17

Merged
merged 6 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions debian/jitsi-autoscaler-sidecar.postinst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ case "$1" in
INSTANCE_TYPE="JVB"
POLLING_URL="http://localhost:3000/sidecar/poll"
STATUS_URL="http://localhost:3000/sidecar/status"
SHUTDOWN_URL="http://localhost:3000/sidecar/shutdown"

# and we're done with debconf
db_stop
Expand Down Expand Up @@ -99,6 +100,7 @@ case "$1" in
sed -i s#INSTANCE_TYPE=#INSTANCE_TYPE=${INSTANCE_TYPE}#g $SIDECAR_CONFIG
sed -i s#POLLING_URL=#POLLING_URL=${POLLING_URL}#g $SIDECAR_CONFIG
sed -i s#STATUS_URL=#STATUS_URL=${STATUS_URL}#g $SIDECAR_CONFIG
sed -i s#SHUTDOWN_URL=#SHUTDOWN_URL=${SHUTDOWN_URL}#g $SIDECAR_CONFIG
fi
;;

Expand Down
4 changes: 4 additions & 0 deletions env.example
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ POLLING_URL=
# e.g. 'http://localhost:3000/sidecar/status'
STATUS_URL=

# The autoscaler URL used by the sidecar to report final shutdown status (required)
# e.g. 'http://localhost:3000/sidecar/shutdown'
SHUTDOWN_URL=

# The command the sidecar can run on the local instance to gracefully shut it down
#GRACEFUL_SHUTDOWN_SCRIPT=/usr/local/bin/graceful_shutdown.sh

Expand Down
36 changes: 36 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const autoscalePoller = new Poller({
pollUrl: config.PollingURL,
statusUrl: config.StatusURL,
statsUrl: config.StatsReportURL,
shutdownUrl: config.ShutdownURL,
instanceDetails,
asapRequest
});
Expand All @@ -52,6 +53,7 @@ let statsReport: StatsReport;

let reconfigureLock = false;
let shutdownLock = false;
let shutdownReported = false;

interface JibriMetadata {
[key: string]: string;
Expand Down Expand Up @@ -90,6 +92,32 @@ async function jibriStateWebhook(req: Request, res: Response) {
res.send('{"status":"OK"}');
}

/**
* The hook to report final shutdown to server
*
* @param req the request.
* @param res the response.
*/
async function instanceShutdownWebhook(req: Request, res: Response) {
// update global stats report with
if (shutdownReported) {
res.status(200);
shutdownReported = true;
res.send('{"status":"OK", "message":"Already reported shutdown"}');
} else {
const ret = await autoscalePoller.reportShutdown();

if (ret) {
res.status(200);
shutdownReported = true;
res.send('{"status":"OK"}');
} else {
res.status(500);
res.send('{"status":"FAILED"}');
}
}
}

/**
* Polls stats every 1 second.
*/
Expand Down Expand Up @@ -180,6 +208,14 @@ app.get('/health', (req: express.Request, res: express.Response) => {
res.send('healthy!');
});

app.post('/hook/v1/shutdown', async (req, res, next) => {
try {
await instanceShutdownWebhook(req, res);
} catch (err) {
next(err);
}
});

app.post('/hook/v1/status', async (req, res, next) => {
try {
await jibriStateWebhook(req, res);
Expand Down
22 changes: 22 additions & 0 deletions src/autoscale_poller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface AutoscalePollerOptions {
pollUrl: string;
statusUrl: string;
statsUrl: string;
shutdownUrl: string;
instanceDetails: InstanceDetails;
asapRequest: AsapRequest;
}
Expand All @@ -33,6 +34,7 @@ export default class AutoscalePoller {
private pollUrl: string;
private statusUrl: string;
private statsUrl: string;
private shutdownUrl: string;
private asapRequest: AsapRequest;

/**
Expand All @@ -43,12 +45,32 @@ export default class AutoscalePoller {
this.pollUrl = options.pollUrl;
this.statusUrl = options.statusUrl;
this.statsUrl = options.statsUrl;
this.shutdownUrl = options.shutdownUrl;
this.instanceDetails = options.instanceDetails;
this.asapRequest = options.asapRequest;

this.pollWithStats = this.pollWithStats.bind(this);
}

/**
* Reports shutdown status by sending a json.
*/
async reportShutdown(): Promise<boolean> {
try {
if (!this.shutdownUrl) {
throw new Error('No shutdown URL configured');
}
await this.asapRequest.postJson(this.shutdownUrl, this.instanceDetails);

return true;
} catch (err) {
logger.error('Error sending shutdown report', { err,
traceback: err.traceback });
}

return false;
}

/**
* Reports stats by sending a json.
* @param statsReport
Expand Down
8 changes: 8 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const env = envalid.cleanEnv(process.env, {
ASAP_JWT_AUD: envalid.str({ default: 'jitsi-autoscaler' }),
ENABLE_REPORT_STATS: envalid.bool({ default: false }),
POLLING_URL: envalid.str(),
SHUTDOWN_URL: envalid.str({ default: '' }),
STATUS_URL: envalid.str(),
STATS_RETRIEVE_URL: envalid.str({ default: '' }),
STATS_REPORT_URL: envalid.str({ default: '' }),
Expand All @@ -37,7 +38,14 @@ export default {

// number of seconds to wait between polling for shutdown
ShutdownPollingInterval: env.SHUTDOWN_POLLING_INTERVAL,

// url for reporting final shutdown
ShutdownURL: env.SHUTDOWN_URL,

// url to poll for server commands
PollingURL: env.POLLING_URL,

// url to report status and stats
StatusURL: env.STATUS_URL,

// number of seconds to wait before polling for stats
Expand Down
Loading