背景工作
jobs 能力會加入持久的工作佇列與背景 worker。已登入的使用者選取一個檔案;App 以該使用者的工作階段讀取一次,並在套件的資料資料夾中保留私有副本。使用者登出或關閉瀏覽器後,worker 仍會處理該副本。隨附的 worker 會計算檔案的 SHA-256 摘要。結果只留在套件內:背景工作絕不會寫入使用者的資料夾。若需要那樣做,請見 Delegate。
背景工作以套件帳號執行,不需要管理員設定。App 不會為背景工作儲存 cookie、工作階段 ID、token 或密碼。每位使用者各有一組獨立的背景工作。
新專案:
synopkgland init -t native-go --with jobs my-jobs既有專案:
synopkgland add jobs兩者都會在 dsm-package.yaml 設定:
capabilities: jobs: truejobs: true 等同 jobs: { worker: sha256-v1 }。不接受其他 worker 名稱。
| 組合 | 結果 |
|---|---|
jobs 搭配 daemon | CAPABILITY_COMBINATION_INVALID,除非宣告了 lifetime: until-revoked 的 delegate |
jobs 搭配 binary 後端 | CAPABILITY_UNSUPPORTED |
armv7 上的 jobs | 已建置,尚未在 NAS 上驗證 |
delegate | 會自動開啟 jobs |
產生的 Vue UI 會加入背景工作頁。plain UI 沒有背景工作頁,但 route 仍存在。
提交、查看、取消
Section titled “提交、查看、取消”背景工作頁讓使用者選取檔案、提交、查看狀態、取消並開啟結果。若用自己的程式碼,請透過 ctx.call 呼叫這些方法。全部都需要已登入的使用者。
| 方法 | 參數 | 結果 |
|---|---|---|
bg.status | {} | 限制、佇列數量,以及 worker 是否在執行 |
bg.browse | { folder?, offset } | 一頁使用者看得到的資料夾與檔案。不需要 files 能力 |
bg.jobs.submit | { key, folder, relative } | { job, duplicate } |
bg.jobs.list | {} | { jobs },最新的在前 |
bg.jobs.get | { id } | { job } |
bg.jobs.cancel | { id } | { job } |
bg.jobs.result | { id } | { job, result };若背景工作還沒有結果則為 not_ready |
const key = crypto.randomUUID()const { job } = await ctx.call<{ job: { id: string; state: string } }>('bg.jobs.submit', { key, folder: '/home', relative: 'report.txt',})const { result } = await ctx.call<{ result: { sha256: string; bytes: number } }>('bg.jobs.result', { id: job.id })key用來識別請求:1 到 64 個英文字母、數字、句點、底線與連字號。再次送出相同的 key 會回傳同一個背景工作並帶有duplicate: true,所以重試是安全的。key 在各擁有者之間互相獨立。folder是 File Station 的資料夾路徑,relative是其下的檔案。- 結果是 JSON,不是檔案:
{ jobId, worker, workerRevision, algorithm: "sha256", sha256, bytes, inputDigest, name }。 - 背景工作的狀態依序為
queued、running,最後是succeeded、failed、canceled或interrupted。worker 停止時正在執行的背景工作會變成interrupted,且不會重新執行。 - 關閉瀏覽器或登出不會取消背景工作。只有
bg.jobs.cancel會。
匯入之後,擁有者可以讓私有副本依排程重複執行。App 會固定住位元組與摘要。它不會再次讀取 NAS 檔案,所以之後來源檔案的變更不會有影響。
| 方法 | 參數 | 誰可以 |
|---|---|---|
bg.schedules.list | {} | 擁有者看到自己的,管理員看到全部 |
bg.schedules.create | { key, jobId, intervalSeconds, consent: true } | 來源背景工作的擁有者 |
bg.schedules.disable、bg.schedules.delete | { id } | 擁有者或管理員 |
bg.schedules.enable | { id, consent: true } | 僅限管理員 |
intervalSeconds必須剛好是3600(每小時)、86400(每天)或604800(每週)。consent必須是true,否則呼叫會以bad_request失敗。- 來源背景工作(
jobId)必須是你自己的,且狀態為succeeded。別人的背景工作會回傳not_found。尚未完成的背景工作、排程產生的執行,或副本已不存在的背景工作,會回傳input-unavailable。請重新匯入檔案。 - 固定住的副本會計入你的 1 MiB 與套件的 16 MiB 限制。
- 延遲超過 5 秒的觸發會記為錯過。錯過的執行絕不會補跑。排程不保證準確時間,也不保證只執行一次。
- 排程執行會為手動的背景工作保留至少 4 個佇列空位。
誰看得到哪些背景工作
Section titled “誰看得到哪些背景工作”擁有者是 DSM 使用者名稱,加上 DSM 為它解析出的數字 UID。
- 一般使用者只能列出、讀取、取消自己的背景工作並取得其結果。不存在的背景工作 ID,與屬於別人的背景工作,都會回傳
not_found。 - 管理員可以看到並取消所有背景工作。
bg.jobs.purge({ owner: { user, uid } })會移除某位擁有者的背景工作,僅限管理員。 - 若 DSM 無法解析使用者的 UID,呼叫會以
identity_unavailable失敗。對管理員而言,這只影響提交與建立排程。 - 被刪除後以相同名稱但不同 UID 重新建立的帳號,無法存取先前的背景工作。若名稱與 UID 都被重複使用,則無法區分背景工作。
- 之後變更來源檔案的權限,不會收回已存在的副本或結果。
| 項目 | 限制 |
|---|---|
| 同時執行的背景工作 | 1 |
| 佇列中的背景工作 | 16 |
| 輸入檔案 | 512 KiB |
| DSM 7.1 上的輸入檔案 | DSM 7.1 傳送檔案時沒有 Content-Disposition。檔案不超過 4 KiB 且整個內容就是一個 DSM 回應(含 success 欄位的 JSON 物件)時,會被當成該回應而拒絕 |
| 私有副本與結果的總量 | 16 MiB |
| 單一背景工作的時間 | 60 秒(timeout) |
| 每位擁有者的待處理背景工作(含管理員) | 2 |
| 每位擁有者的私有資料(含管理員) | 1 MiB。每個待處理或保留的結果另外計 512 位元組 |
| 保留的已完成背景工作 | 64 |
| 每個套件的排程 | 8 |
| 排程間隔 | 3600、86400 或 604800 秒 |
兩個 512 KiB 的完整輸入,超過一位擁有者能保有的量。資料存放在套件的 App 資料資料夾。套件停止時與一般解除安裝時都會保留。請見資料與移除。
| 錯誤碼 | 原因 | 解法 |
|---|---|---|
session_required | 沒有已登入的使用者,或讀取檔案所需的 DSM 工作階段不存在 | 重新登入。使用獨立登入時,呼叫需要 DSM id cookie |
dsm_session_required | 獨立登入已開啟,而提交或瀏覽需要 DSM id cookie | 在相同的主機名稱登入 DSM |
limit-exceeded | 檔案超過 512 KiB | 選擇較小的檔案 |
queue-full | 已有 16 個背景工作在佇列中 | 等待後重試 |
quota-exceeded | 套件的私有儲存空間(16 MiB)已滿 | 等待背景工作完成,或請管理員清除 |
owner-queue-full | 你已有 2 個待處理的背景工作 | 等待或取消其中一個 |
owner-quota-exceeded | 你保有 1 MiB 的私有資料 | 等待結果被清除 |
schedule-full | 套件已有 8 個排程 | 刪除一個 |
input-unavailable | 排程所需的保留副本已不存在 | 重新匯入檔案 |
conflict | 同一個 key 被用於不同的輸入、背景工作或間隔,或取消了已完成的背景工作 | 使用新的 key;檢查狀態 |
not_ready | 背景工作還沒有結果 | 等到 succeeded |
not_found | 沒有這個背景工作,或它屬於其他使用者 | 重新整理清單 |
identity_unavailable | DSM 無法解析使用者的 UID | 重試;檢查 DSM 帳號 |
jobs_busy | 工作儲存區被鎖定超過 5 秒 | 重試 |
admin_required | 僅限管理員的方法,例如 bg.jobs.purge | 使用管理員帳號 |
失敗的背景工作會有 errorCode:
errorCode | 原因 |
|---|---|
timeout | 背景工作執行超過 60 秒 |
input-changed | 私有副本與儲存的摘要不符 |
worker-error | worker 失敗 |
worker-stopped | 背景工作執行期間 worker 停止。狀態為 interrupted |
worker-changed | 背景工作是在不同版本的 worker 下排入佇列的。狀態為 interrupted |
admission-interrupted | worker 重新啟動時,正在進行交給 delegate 的流程。狀態為 interrupted |
錯誤碼的說明請見錯誤碼。