Skip to content

Commit

Permalink
feat(action): handle user cancellation
Browse files Browse the repository at this point in the history
This is useful in start mode where one can cancel before the
instance is actually ready. This way a best-effort is produced
to clean up any spawned instance instead of it turning into a
zombie.
  • Loading branch information
soonum committed Dec 10, 2024
1 parent ff32326 commit 1cfd679
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
45 changes: 45 additions & 0 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,27 @@ const slab = require('./slab')
const config = require('./config')
const core = require('@actions/core')
const { waitForRunnerRegistered } = require('./gh')
const utils = require('./utils')

function setOutput(label) {
core.setOutput('label', label)
}

// This variable should only be defined for cleanup purpose.
let runner_name

async function cleanup() {
if (runner_name) {
core.info('Stop instance after cancellation')
await slab.stopInstanceRequest(runner_name)
}
}

process.on('SIGINT', async function () {
await cleanup()
process.exit()
})

async function start() {
const provider = config.input.backend

Expand All @@ -15,6 +31,7 @@ async function start() {
for (let i = 1; i <= 3; i++) {
try {
start_instance_response = await slab.startInstanceRequest()
runner_name = start_instance_response.runner_name
break
} catch (error) {
core.info('Retrying request now...')
Expand Down
28 changes: 28 additions & 0 deletions src/slab.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ async function waitForInstance(taskId, taskName) {
const task_status = body[taskName].status.toLowerCase()

if (task_status === 'done') {
if (taskName === 'start') {
await acknowledgeTaskDone(taskId)
}
await removeTask(taskId)
return body
} else if (task_status === 'failed') {
Expand Down Expand Up @@ -192,6 +195,31 @@ async function removeTask(taskId) {
}
}

async function acknowledgeTaskDone(taskId) {
const url = config.input.slabUrl
const route = `task_ack_done/${config.githubContext.repo}/${taskId}`
let response

try {
response = await fetch(concat_path(url, route), {
method: 'POST'
})
} catch (error) {
core.error(`Failed to acknowledge task done with ID: ${taskId}`)
throw error
}

if (response.ok) {
core.debug('Instance task successfully acknowledged')
return response
} else {
core.error(
`Instance task acknowledgment request has failed (ID: ${taskId}, HTTP status code: ${response.status})`
)
throw new Error('task acknowledging failed')
}
}

module.exports = {
startInstanceRequest,
stopInstanceRequest,
Expand Down

0 comments on commit 1cfd679

Please sign in to comment.