−25%

על Windows בתשלום שנתי, עד 31.10. לחבילות

EQVPS
התחלה

SDK של TypeScript לארגזי חול ב־5 דקות: מ־npm i @eqvps/sdk ועד ההרצה הראשונה

התקינו את ‎@eqvps/sdk, הפעילו ארגז חול של Firecracker מ־Node.js, ‏Deno או Bun, הריצו בו קוד Python, ‏Node ו־shell, העבירו קבצים ועקבו בזמן אמת אחרי משימה ארוכה. שישה שלבים עם כל שורת קוד.

המדריך הזה מריץ ארגז חול מ־JavaScript או מ־TypeScript. תפעילו microVM מבודד של Firecracker, תריצו קוד בשלוש שפות, תעבירו קבצים ותעקבו אחרי הפלט של משימה ארוכה. כל שלב הוא קטע קוד קצר.

צריך Node.js 18+‎ (או Deno, או Bun) וחשבון EQVPS.

1. השיגו טוקן

ה־SDK מזדהה עם טוקן חשבון רגיל. איך משיגים אותו מלוח הבקרה, מה־API או משרת ה־MCP מוסבר בחיבור החשבון.

export EQVPS_API_KEY="your-token"

חשבון חדש בלי יתרה מקבל קרדיט של 1 דולר לארגזי חול כשהוא יוצר ארגז חול בפעם הראשונה. זה מספיק למדריך הזה פעמים רבות.

2. התקינו את ה־SDK

npm i @eqvps/sdk

הדוגמאות משתמשות במודולי ES וב־await ברמה העליונה. שמרו אותן כקבצי .mjs, או כ־.ts והריצו עם npx tsx.

3. הפעילו ארגז חול והריצו קוד

import { Sandbox } from "@eqvps/sdk";

await Sandbox.with({ tariff: "small" }, async (sb) => {
  console.log(sb.id);
  const r = await sb.run("import platform; print(platform.python_version())");
  console.log(r.exit_code, r.stdout);
});

הפלט הוא מזהה ארגז החול (sb_ ועוד 24 תווים), ואחריו 0 3.12.x. ‏Sandbox.with מוחק את ארגז החול כשהפונקציה מסתיימת, גם אם היא זורקת שגיאה.

שפת ברירת המחדל היא Python. שתי האחרות במרחק אפשרות אחת:

await Sandbox.with({}, async (sb) => {
  const js = await sb.run("console.log(process.version)", { language: "node" });
  const sh = await sb.run("uname -r && nproc", { language: "bash" });
  console.log(js.stdout, sh.stdout);
});

סקריפט שנכשל לא זורק כלום. בדקו את r.ok, שהוא true כש־exit_code הוא 0 והפקודה לא הגיעה למגבלת הזמן.

4. פקודות shell וחבילות

‏exec מקבל מחרוזת shell או מערך argv. לארגז החול יש גישה לאינטרנט, כך שהתקנות דרך npm ו־pip עובדות:

await Sandbox.with({ tariff: "small" }, async (sb) => {
  await sb.exec("mkdir -p /root/app && cd /root/app && npm init -y && npm i lodash", { timeout: 55 });
  const r = await sb.exec(["node", "-e", "console.log(require('/root/app/node_modules/lodash').VERSION)"]);
  console.log(r.stdout);
});

קריאה סינכרונית נמשכת לכל היותר 55 שניות. כל מה שארוך יותר עובר למשימת רקע (שלב 6).

5. קבצים

await Sandbox.with({}, async (sb) => {
  await sb.upload("/root/input.json", JSON.stringify({ values: [3, 5, 8] }));
  await sb.run("import json; d = json.load(open('/root/input.json')); open('/root/out.txt', 'w').write(str(sum(d['values'])))");
  console.log(await sb.downloadText("/root/out.txt"));   // 16
});

‏upload מקבל מחרוזת או Uint8Array. ‏download מחזיר Uint8Array, ו־downloadText מחרוזת. העברה אחת מוגבלת ל־5 MB.

6. משימות ארוכות עם פלט חי

await Sandbox.with({ tariff: "standard" }, async (sb) => {
  const task = await sb.exec("for i in 1 2 3 4 5; do echo step $i; sleep 20; done", { background: true });
  const res = await task.wait({ onOutput: (out) => process.stdout.write(out) });
  console.log(res.state, res.exit_code);   // done 0
});

המשימה חוזרת מיד ואין לה מגבלה של 55 שניות. ‏wait בודק כברירת מחדל כל 2 שניות (את זה משנה pollIntervalMs). ‏task.kill() עוצר אותה, ו־sb.task(id) מתחבר אליה מחדש מתהליך אחר.

שגיאות

import { Sandbox, InsufficientBalanceError, RateLimitError } from "@eqvps/sdk";

try {
  await Sandbox.with({}, async (sb) => console.log((await sb.run("print(1)")).stdout));
} catch (e) {
  if (e instanceof InsufficientBalanceError) console.log("Top up the balance");
  else if (e instanceof RateLimitError) console.log("Busy, retry in", e.retryAfter);
  else throw e;
}

ה־SDK מנסה שוב בעצמו 429 ו־503, עד שלוש פעמים, כשהשרת שולח Retry-After. ה־429 הנפוץ ביותר נובע מהרצה של יותר משתי פקודות בבת אחת באותו חשבון. כל המחלקות מופיעות במדריך ה־SDK.

העלות של המדריך

כל דוגמה חיה כמה שניות וחויבה לפי המינימום של 60 שניות: 0.00055 דולר ב־small, ‏0.0011 דולר ב־standard. המשימה משלב 6 רצה כ־100 שניות ב־standard, בערך 0.002 דולר. הכול יחד הרבה פחות מסנט. רשימת המחירים המלאה במגבלות וחיוב של ארגזי חול.

השלבים הבאים

שאלות נפוצות

באילו סביבות ריצה ‎@eqvps/sdk תומך?

Node.js 18 ומעלה, Deno ו־Bun. אין לו תלויות והוא משתמש ב־fetch המובנה, לכן הוא רץ גם בדפדפן, אבל אל תשימו את טוקן החשבון בקוד צד לקוח.

ארגז החול יכול להריץ Python אם האפליקציה שלי כתובה ב־TypeScript?

כן. השפה של האפליקציה שלכם והשפה של הקוד בארגז החול לא תלויות זו בזו. ‏run מקבל language מסוג python, ‏node או bash, ו־exec מריץ כל פקודת shell.

איך מוודאים שארגז החול יימחק?

השתמשו ב־Sandbox.with(options, fn), שמוחק את ארגז החול כש־fn מסתיימת או זורקת שגיאה. ב־TypeScript 5.2 ומעלה אפשר גם לכתוב await using sb = await Sandbox.create().

מה run מחזיר כשהקוד נכשל?

ExecResult עם exit_code שאינו אפס והשגיאה ב־stderr. שום דבר לא נזרק. חריגות יש רק בשגיאות API, כמו טוקן לא תקין או יתרה ריקה.

תגובות

אין עדיין תגובות. היו הראשונים.

השאירו תגובה

התגובות עוברות מודרציה לפני שהן מופיעות.