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

feat(action): handle user cancellation #46

Merged
merged 1 commit into from
Dec 11, 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
48 changes: 47 additions & 1 deletion 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
31 changes: 30 additions & 1 deletion src/slab.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ async function startInstanceRequest() {
const details = {
backend: {
provider,
profile: config.input.profile
profile: config.input.profile,
create_watchdog_task: true
}
}

Expand Down Expand Up @@ -127,6 +128,9 @@ async function waitForInstance(taskId, taskName) {
const task_status = body[taskName].status.toLowerCase()

if (task_status === 'done') {
if (taskName === 'start') {
await acknowledgeTaskDone(taskId)
}
IceTDrinker marked this conversation as resolved.
Show resolved Hide resolved
Comment on lines +131 to +133
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the process is:

ask for start -> slab starts instance, starts watchdog -> action waits for instance -> acknowledge ?

isn't there a risk of slab killing the instance before the action can aknowledge ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also is there a risk of aknowledging before Slab is waiting for an aknwoledge ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't there a risk of slab killing the instance before the action can aknowledge ?

Reasonably, no. The sleeping time before killing the instance is 5 minutes on Slab side, AFTER the spawn is over.

also is there a risk of aknowledging before Slab is waiting for an aknwoledge ?

No this is enforced on Slab side, you cannot acknowledge an InProgress or a Failed task (it's basically a no-op)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible for the action to acknowledge an in progress task ?

and if so, can it say "ok I acknowledged, now I do something else" and never acknowledges again, meaning slab could kill the instance ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope it's not possible to acknowledge an in progress task. The implementation imposes the acknowledge call to happen after a Done task has been received.

await removeTask(taskId)
return body
} else if (task_status === 'failed') {
Expand Down Expand Up @@ -192,6 +196,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
Loading