跳到內容
Syno Package Land
語言: 繁體中文

背景工作

jobs 能力會加入持久的工作佇列與背景 worker。已登入的使用者選取一個檔案;App 以該使用者的工作階段讀取一次,並在套件的資料資料夾中保留私有副本。使用者登出或關閉瀏覽器後,worker 仍會處理該副本。隨附的 worker 會計算檔案的 SHA-256 摘要。結果只留在套件內:背景工作絕不會寫入使用者的資料夾。若需要那樣做,請見 Delegate。

背景工作以套件帳號執行,不需要管理員設定。App 不會為背景工作儲存 cookie、工作階段 ID、token 或密碼。每位使用者各有一組獨立的背景工作。

新專案:

Terminal window
synopkgland init -t native-go --with jobs my-jobs

既有專案:

Terminal window
synopkgland add jobs

兩者都會在 dsm-package.yaml 設定:

capabilities:
jobs: true

jobs: true 等同 jobs: { worker: sha256-v1 }。不接受其他 worker 名稱。

組合結果
jobs 搭配 daemonCAPABILITY_COMBINATION_INVALID,除非宣告了 lifetime: until-revoked 的 delegate
jobs 搭配 binary 後端CAPABILITY_UNSUPPORTED
armv7 上的 jobs已建置,尚未在 NAS 上驗證
delegate會自動開啟 jobs

產生的 Vue UI 會加入背景工作頁。plain UI 沒有背景工作頁,但 route 仍存在。

背景工作頁讓使用者選取檔案、提交、查看狀態、取消並開啟結果。若用自己的程式碼,請透過 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 個佇列空位。

擁有者是 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_unavailableDSM 無法解析使用者的 UID重試;檢查 DSM 帳號
jobs_busy工作儲存區被鎖定超過 5 秒重試
admin_required僅限管理員的方法,例如 bg.jobs.purge使用管理員帳號

失敗的背景工作會有 errorCode:

errorCode原因
timeout背景工作執行超過 60 秒
input-changed私有副本與儲存的摘要不符
worker-errorworker 失敗
worker-stopped背景工作執行期間 worker 停止。狀態為 interrupted
worker-changed背景工作是在不同版本的 worker 下排入佇列的。狀態為 interrupted
admission-interruptedworker 重新啟動時,正在進行交給 delegate 的流程。狀態為 interrupted

錯誤碼的說明請見錯誤碼。