use background task to avoid timeout

This commit is contained in:
Laura Abro
2025-04-29 11:09:29 -03:00
parent 6cf7e0db0e
commit f4b0fc4e2e
9 changed files with 198 additions and 107 deletions

View File

@ -2,7 +2,7 @@ import { TASK_ID, namespaceWrapper } from "@_koii/namespace-wrapper";
import "dotenv/config";
import os from "os";
const imageUrl = "docker.io/labrocadabro/prometheus-summarizer:0.2";
const imageUrl = "docker.io/labrocadabro/prometheus-summarizer:0.4";
function getHostIP() {
const interfaces = os.networkInterfaces();

View File

@ -8,6 +8,7 @@ import { checkGitHub } from "../utils/githubCheck";
import { LogLevel } from "@_koii/namespace-wrapper/dist/types";
import { actionMessage } from "../utils/constant";
import { errorMessage } from "../utils/constant";
import { v4 as uuidv4 } from "uuid";
dotenv.config();
export async function task(roundNumber: number): Promise<void> {
@ -128,11 +129,22 @@ export async function task(roundNumber: number): Promise<void> {
}
const requiredWorkResponseData = await requiredWorkResponse.json();
console.log("[TASK] requiredWorkResponseData: ", requiredWorkResponseData);
const uuid = uuidv4();
await namespaceWrapper.storeSet(`uuid-${roundNumber}`, uuid);
const podcallPayload = {
taskId: TASK_ID,
roundNumber,
uuid,
};
const podCallSignature = await namespaceWrapper.payloadSigning(podcallPayload, stakingKeypair.secretKey);
const jsonBody = {
taskId: TASK_ID,
round_number: String(roundNumber),
task_id: TASK_ID,
round_number: roundNumber,
repo_url: `https://github.com/${requiredWorkResponseData.data.repo_owner}/${requiredWorkResponseData.data.repo_name}`,
podcall_signature: podCallSignature,
};
console.log("[TASK] jsonBody: ", jsonBody);
try {
@ -144,70 +156,12 @@ export async function task(roundNumber: number): Promise<void> {
body: JSON.stringify(jsonBody),
});
console.log("[TASK] repoSummaryResponse: ", repoSummaryResponse);
console.log("[TASK] repoSummaryResponse.data.result.data ", repoSummaryResponse.data.result.data);
const payload = {
taskId: TASK_ID,
action: "add-todo-pr",
roundNumber: roundNumber,
prUrl: repoSummaryResponse.data.result.data.pr_url,
stakingKey: stakingKey,
};
console.log("[TASK] Signing payload: ", payload);
if (repoSummaryResponse.status === 200) {
try {
const signature = await namespaceWrapper.payloadSigning(payload, stakingKeypair.secretKey);
console.log("[TASK] signature: ", signature);
const addPrToSummarizerTodoResponse = await fetch(`${middleServerUrl}/summarizer/worker/add-todo-pr`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ signature: signature, stakingKey: stakingKey }),
});
console.log("[TASK] addPrToSummarizerTodoResponse: ", addPrToSummarizerTodoResponse);
} catch (error) {
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.ISSUE_FAILED_TO_ADD_PR_TO_SUMMARIZER_TODO);
console.error("[TASK] Error adding PR to summarizer todo:", error);
}
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.ISSUE_SUCCESSFULLY_SUMMARIZED);
} else {
// post this summary response to slack` to notify the team
// THE HOOK IS ALREADY DISABLED
// try{
// const slackResponse = await fetch('https://hooks.slack.com/services/', {
// method: "POST",
// headers: {
// "Content-Type": "application/json",
// },
// body: JSON.stringify({
// text: `[TASK] Error summarizing issue:\nStatus: ${repoSummaryResponse.status}\nData: ${JSON.stringify(repoSummaryResponse.data, null, 2)}`
// }),
// });
// console.log("[TASK] slackResponse: ", slackResponse);
// }catch(error){
// console.error("[TASK] Error posting to slack:", error);
// }
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.ISSUE_FAILED_TO_BE_SUMMARIZED);
if (repoSummaryResponse.status !== 200) {
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.ISSUE_SUMMARIZATION_FAILED);
}
} catch (error) {
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.ISSUE_FAILED_TO_BE_SUMMARIZED);
// try{
// const slackResponse = await fetch('https://hooks.slack.com/services', {
// method: "POST",
// headers: {
// "Content-Type": "application/json",
// },
// body: JSON.stringify({
// text: `[TASK] Error summarizing issue:\n ${JSON.stringify(error)}`
// }),
// });
// console.log("[TASK] slackResponse: ", slackResponse);
// }catch(error){
// console.error("[TASK] Error posting to slack:", error);
// }
console.error("[TASK] EXECUTE TASK ERROR:", JSON.stringify(error));
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.ISSUE_SUMMARIZATION_FAILED);
console.error("[TASK] EXECUTE TASK ERROR:", error);
}
} catch (error) {
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.UNKNOWN_ERROR);

View File

@ -1,9 +1,10 @@
import { namespaceWrapper, app } from "@_koii/task-manager/namespace-wrapper";
import { namespaceWrapper, app, TASK_ID } from "@_koii/task-manager/namespace-wrapper";
import { getLeaderNode } from "../utils/leader";
import { task } from "./1-task";
import { submission } from "./2-submission";
import { audit } from "./3-audit";
import { taskRunner } from "@_koii/task-manager";
import { middleServerUrl, status } from "../utils/constant";
/**
*
@ -53,4 +54,95 @@ export async function routes() {
const submitDistributionResult = await taskRunner.submitDistributionList(Number(roundNumber));
res.status(200).json({ result: submitDistributionResult });
});
app.post("/add-todo-pr", async (req, res) => {
const signature = req.body.signature;
const prUrl = req.body.prUrl;
const roundNumber = Number(req.body.roundNumber);
const success = req.body.success;
const message = req.body.message;
console.log("[TASK] req.body", req.body);
try {
if (success) {
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.ISSUE_SUMMARIZATION_SUCCEEDED);
} else {
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.ISSUE_SUMMARIZATION_FAILED);
console.error("[TASK] Error summarizing repository:", message);
return;
}
const uuid = await namespaceWrapper.storeGet(`uuid-${roundNumber}`);
console.log("[TASK] uuid: ", uuid);
if (!uuid) {
throw new Error("No uuid found");
}
const currentRound = await namespaceWrapper.getRound();
if (roundNumber !== currentRound) {
throw new Error(`Invalid round number: ${roundNumber}. Current round: ${currentRound}.`);
}
const publicKey = await namespaceWrapper.getMainAccountPubkey();
const stakingKeypair = await namespaceWrapper.getSubmitterAccount();
if (!stakingKeypair) {
throw new Error("No staking key found");
}
const stakingKey = stakingKeypair.publicKey.toBase58();
const secretKey = stakingKeypair.secretKey;
if (!publicKey) {
throw new Error("No public key found");
}
const payload = await namespaceWrapper.verifySignature(signature, stakingKey);
if (!payload) {
throw new Error("Invalid signature");
}
console.log("[TASK] payload: ", payload);
const data = payload.data;
if (!data) {
throw new Error("No signature data found");
}
const jsonData = JSON.parse(data);
if (jsonData.taskId !== TASK_ID) {
throw new Error(`Invalid task ID from signature: ${jsonData.taskId}. Actual task ID: ${TASK_ID}`);
}
if (jsonData.roundNumber !== currentRound) {
throw new Error(
`Invalid round number from signature: ${jsonData.roundNumber}. Current round: ${currentRound}.`,
);
}
if (jsonData.uuid !== uuid) {
throw new Error(`Invalid uuid from signature: ${jsonData.uuid}. Actual uuid: ${uuid}`);
}
const middleServerPayload = {
taskId: jsonData.taskId,
roundNumber,
prUrl,
stakingKey,
publicKey,
action: "add-todo-pr",
};
const middleServerSignature = await namespaceWrapper.payloadSigning(middleServerPayload, secretKey);
const middleServerResponse = await fetch(`${middleServerUrl}/summarizer/worker/add-todo-pr`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ signature: middleServerSignature, stakingKey: stakingKey }),
});
console.log("[TASK] Add PR Response: ", middleServerResponse);
if (middleServerResponse.status !== 200) {
throw new Error(`Posting to middle server failed: ${middleServerResponse.statusText}`);
}
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.SAVING_TODO_PR_SUCCEEDED);
res.status(200).json({ result: "Successfully saved PR" });
} catch (error) {
console.error("[TASK] Error adding PR to summarizer todo:", error);
await namespaceWrapper.storeSet(`result-${roundNumber}`, status.SAVING_TODO_PR_FAILED);
res.status(400).json({ error: "Failed to save PR" });
}
});
}

View File

@ -1,22 +1,22 @@
import dotenv from "dotenv";
dotenv.config();
export const status = {
ISSUE_FAILED_TO_BE_SUMMARIZED: "Issue failed to be summarized",
ISSUE_SUCCESSFULLY_SUMMARIZED: "Issue successfully summarized",
ISSUE_SUMMARIZATION_FAILED: "Issue summarization failed",
ISSUE_SUMMARIZATION_SUCCEEDED: "Issue successfully summarized",
NO_ISSUES_PENDING_TO_BE_SUMMARIZED: "No issues pending to be summarized",
ROUND_LESS_THAN_OR_EQUAL_TO_1: "Round <= 1",
NO_ORCA_CLIENT: "No orca client",
NO_CHOSEN_AS_ISSUE_SUMMARIZER: "No chosen as issue summarizer",
NOT_SELECTED_AS_SUMMARIZER: "Not selected as summarizer",
UNKNOWN_ERROR: "Unknown error",
STAR_ISSUE_FAILED: "Star issue failed",
GITHUB_CHECK_FAILED: "GitHub check failed",
ANTHROPIC_API_KEY_INVALID: "Anthropic API key invalid",
ANTHROPIC_API_KEY_NO_CREDIT: "Anthropic API key has no credit",
NO_DATA_FOR_THIS_ROUND: "No data for this round",
ISSUE_FAILED_TO_ADD_PR_TO_SUMMARIZER_TODO: "Issue failed to add PR to summarizer todo",
}
SAVING_TODO_PR_FAILED: "Summarizer todo PR not saved",
SAVING_TODO_PR_SUCCEEDED: "Summarizer todo PR saved",
};
export const errorMessage = {
ISSUE_FAILED_TO_BE_SUMMARIZED: "We couldn't summarize this issue. Please try again later.",
@ -32,7 +32,7 @@ export const errorMessage = {
ANTHROPIC_API_KEY_NO_CREDIT: "Your Anthropic API key has no remaining credits.",
NO_DATA_FOR_THIS_ROUND: "There is no data available for this round.",
ISSUE_FAILED_TO_ADD_PR_TO_SUMMARIZER_TODO: "We couldn't add the PR to the summarizer todo list.",
}
};
export const actionMessage = {
ISSUE_FAILED_TO_BE_SUMMARIZED: "We couldn't summarize this issue. Please try again later.",
@ -44,14 +44,17 @@ export const actionMessage = {
UNKNOWN_ERROR: "An unexpected error occurred. Please try again later.",
STAR_ISSUE_FAILED: "We couldn't star the issue. Please try again later.",
GITHUB_CHECK_FAILED: "Please go to the env variable page to update your GitHub Key.",
ANTHROPIC_API_KEY_INVALID: "Please follow the guide under task description page to set up your Anthropic API key correctly.",
ANTHROPIC_API_KEY_INVALID:
"Please follow the guide under task description page to set up your Anthropic API key correctly.",
ANTHROPIC_API_KEY_NO_CREDIT: "Please add credits to continue.",
NO_DATA_FOR_THIS_ROUND: "There is no data available for this round.",
ISSUE_FAILED_TO_ADD_PR_TO_SUMMARIZER_TODO: "We couldn't add the PR to the summarizer todo list. Please try again later.",
}
ISSUE_FAILED_TO_ADD_PR_TO_SUMMARIZER_TODO:
"We couldn't add the PR to the summarizer todo list. Please try again later.",
};
/*********************THE CONSTANTS THAT PROD/TEST ARE DIFFERENT *********************/
export const defaultBountyMarkdownFile = "https://raw.githubusercontent.com/koii-network/prometheus-swarm-bounties/master/README.md"
export const defaultBountyMarkdownFile =
"https://raw.githubusercontent.com/koii-network/prometheus-swarm-bounties/master/README.md";
export const customReward = 400*10**9 // This should be in ROE!
export const customReward = 400 * 10 ** 9; // This should be in ROE!
export const middleServerUrl = "https://ooww84kco0s0cs808w8cg804.dev.koii.network"
export const middleServerUrl = "https://ik8kcow8ksw8gwgoo0ggosko.dev.koii.network";