Dokümanlar menüsü
Yükseltme
Önceki bir sürümün yazdığı depoyu gnl upgrade ile bu sürüme getirin — hangi sırayla, eski süreçler çalışırken ne çalıştırılabilir ve 0.16 ile 0.17 için kodda ne değişmeli.
gnl upgrade ne yapar#
Önceki bir sürümün yazdığı depo, bu sürümün olduğu gibi okumadığı veri tutabilir. gnl upgrade (kodda storage.upgrade()) onu deponun adımlarını çalıştırarak yükseltir: biçim adımları run-status ve schema, sonra paketlerin kaydettiği adımlar. Her adım idempotenttir — yeniden çalıştırılınca bekleyen bir şey bulmaz.
Paketler adımlarını depoya registerUpgradeSteps(storage, factories) ile, depo kurulduğu yerde bir kez ekler; böylece storage.upgrade(), gnl upgrade ve gnl doctor tek bir liste görür. Bir paket adımı paket/adım diye adlandırılır. gnl upgrade kurulu @gnldev/queue ve @gnldev/scheduler'ı kendisi bulur (isteğe bağlı peer'lerdir) ve dışa aktardıkları adımları kaydeder — bayrak yok. gnl init --features job ya da schedule kaydı yeni projeye yazar.
import { registerUpgradeSteps } from '@gnldev/durable';
import { PostgresStorage } from '@gnldev/durable/postgres';
import { queueUpgrade } from '@gnldev/queue';
import { schedulerUpgrade } from '@gnldev/scheduler';
// once, where the store is built: storage.upgrade(), gnl upgrade and gnl doctor see one list
export const storage = registerUpgradeSteps(
new PostgresStorage({ connectionString: process.env.DATABASE_URL! }),
[queueUpgrade, schedulerUpgrade],
);gnl upgrade --list ve --dry-run hiçbir şey yazmaz ve her adımı gösterir (--dry-run ayrıca verinin hangi sürümde olduğunu ve paketin ne beklediğini: "data vX → package vY"). Bayraksız her bekleyen adımı çalıştırır; --only adım yalnızca onları. ran (çalıştı), failed (başarısız), not attempted (after a failure) (hata sonrası denenmedi), pending (bekliyor), waits for older processes (eski süreçleri bekliyor), not registered (kayıtsız) ve done (tamam) olanları basar. Çıkış kodu, başarısız bir adımda ya da kayıtsız bir borçta 1; yalnızca eski süreçleri bekleyen adımlar kaldıysa 0.
afterOlderGone işaretli bir adım, önceki sürümün bir süreci hâlâ çalışırken çalışamaz. Düz bir gnl upgrade onu bekliyor diye bildirir ve çalıştırmaz; önceki süreçlerin gittiğini söylemenin yolu --only'dir. Biçim adımları eldeki işi bekler (gnl pending; --wait bunu gnl pending --wait gibi bekler); afterOlderGone olmayan bir paket adımı beklemez. gnl doctor kayıtlı paket adımlarını, bekleyenleri ve kayıtsız borçları listeler.
0.16'dan 0.17'ye, bu sırayla#
Sıra asıl nokta: kuyruğun verisi biçim değiştiriyor; onu taşıyan adım eski süreçler çalışırken güvenle çalıştırılabilir, eski biçimi silen adım değil.
- Paketleri güncelleyin. Alt sınırlar
ai7.0.149,@ai-sdk/openai4.0.100,@ai-sdk/anthropic4.0.86 ve@ai-sdk/provider4.0.32 — kesilen akışıinterruptedolarak bildiren ilk sürümler.@gnldev/cliartık peer olarak@gnldev/durableister: olmayan projeye npm onu kurar, pnpm ve yarn peer uyarısı verir. - Bu sürümün kuyruk worker'ları başlamadan önce
gnl upgradeçalıştırın. Kuyruk artık işleri kuruluş başına şeritlerde tutuyor, 0.16'nın tekqjobgünlüğünde değil. Adımqueue/lanes: eski günlüğün işlerini şeritlerine taşır (biten iş biter kalır, bekleyen bir kez çalışır) ve eski günlüğe dokunmaz, yani 0.16 worker'ları ve üreticileri hâlâ çalışırken de güvenlidir. İşleri hâlâ o günlükte duran bir depoda bu sürümün worker'ı başlamaz ve neyi çalıştıracağınızı söyler. - Bu sürümü yayına alın, kademeli deploy olarak. Bir 0.16 süreci hâlâ iş ekliyorsa, bu sürümün worker'ları onun eklediklerini taşır; bir 0.16 worker'ının ve yeni bir worker'ın birlikte bulduğu iş bir kez çalışır, çünkü tek bir kiralama vardır.
- Her 0.16 süreci gittiğinde
gnl upgrade --only queue/lanes-cleanupçalıştırın. Eski günlüğü ve imleçlerini siler. Depoyu hâlâ poll ederken görülen bir 0.16 worker'ı varken reddeder: hata ve--dry-runkaç tane olduğunu, her birinin en son ne zaman görüldüğünü ve kaydının ne zaman sona ereceğini söyler. Durdurulmak yerine öldürülen bir worker,ttlMs'i geçene kadar temizliği tutar. - Zamanlayıcının adımı
scheduler/misfire-defaultaynı şekilde: her 0.16 poller'ı gittiğinde, 0.16'nınmisfire: 'skip'ile sakladığı tetikleyicileri "varsayılan"a yeniden yazar. O zamana kadar bu sürüm o kayıtları kendisi varsayılan olarak okur. KoddaupgradeTriggers(journal, opts)'tır; önce bakmak içindryRunverin.
gnl upgrade --dry-run # what would run: data vX → package vY; writes nothing
gnl upgrade # 1. runs queue/lanes (safe beside 0.16 workers and producers)
# ...deploy 0.17 as a rolling deploy; once every 0.16 process is gone:
gnl upgrade --only queue/lanes-cleanup # 2. deletes the old qjob log (refuses while a 0.16 worker is seen)
gnl upgrade --only scheduler/misfire-default # 3. once every 0.16 poller is goneenqueue çağıran ve worker çalıştırmayan bir web sunucusu — kayıt yazmaz, yani temizlik onu görmez. Çalıştırmadan önce her 0.16 üreticisinin de gittiğinden emin olun: daha önce çalıştırılırsa bir 0.16 worker'ı eski günlüğü yeniden baştan okur ve bir 0.16 üreticisi, bu sürümün hiçbir worker'ının artık bakmadığı işler yazar.upgrade()'ı olmayan, kendi yazdığınız bir depoda adımları kaydedecek yer yoktur; her 0.16 süreci gidince onları kendiniz çalıştırın: queueUpgrade(storage)'ın adımları ve onların run()'ı.
Kodda ne değişmeli#
Bunların her biri 0.17 için changelog'un Breaking bölümünde; ait olduğu sayfada ayrıntısı var.
- Canlılık depoya verilir.
liveness'icreateGnl'e ya dacreateWorker'a vermek yerleşik bir depodaLivenessConflictErrorfırlatır. Onu depoya verin:PostgresStoragebirlivenessseçeneği alır, diğer dört depo da (SqliteStorageikinci argüman olarak). Bkz. Depo adaptörleri. listJobsbir sayfa döndürür veorgIdolmadan yalnızca kuruluşu olmayan işleri listeler..items'ı okuyun;listAllJobsoperatörün her kuruluşun işlerini gördüğü görünümdür. Bkz. Arka plan işleri.misfire: 'skip'kalktı, takma adı yok ve varsayılan'latest'. Bir tetikleyici kesintiden sonra artık en eski değil son kaçırılan oluşumu tetikler; eski davranış içinmisfire: 'earliest'verin. Zamanı gelen tetikleyiciler birbirini beklemez veconcurrency'nin varsayılan sınırı yoktur. Bkz. Arka plan işleri.- Özel bir
WorkStoreread,appendManyve ready set ister (appendReady,takeReady,heldReady,deferReady,dropReady);listNamespacesvegetManyisteğe bağlı kalır. Paketle gelen her depo bunları uygular ve uyum seti denetler. - Bir handler'ın çalışma hakkı bir sinyaldir. Bir kuyruk işinin
ctx.signal'i artıklease-lostvetimeoutiçin de abort olur; bir olay handler'ımeta.signalalır, bu yüzdenmeta'yıtoEqualile karşılaştıran bir testtoMatchObjectister. Bkz. Arka plan işleri. - Kesilen bir model akışı
run_unfinished, 502'dir — her akışıfinish_reasonolmadan bitiren bir OpenAI uyumlu uç nokta eskiden 200 cevaplardı. Bir executor'ınclose()'da durdurduğu çalıştırmareleasedbiter. Bkz. REST API. acquireRunLocknowalmaz: kilit deponun saatiyle damgalanır, yani beşinci argüman gitti.storage.upgrade()bir adım hata verinceUpgradeFailedErrorfırlatır, adımın kendi hatasını değil:.reportve.cause'u okuyun, nedeni düzeltin ve yeniden çalıştırın — çalışan adımlar idempotenttir.UpgradeOptions.onlybirreadonly string[]'dir.
import { UpgradeFailedError } from '@gnldev/durable';
try {
await storage.upgrade();
} catch (e) {
if (e instanceof UpgradeFailedError) {
console.error(e.step, e.report, e.cause); // the steps that ran are idempotent: fix the cause, run it again
}
throw e;
}0.15'ten 0.16'ya#
Depo adımı yok. Kodda ve Studio'da kontrol edilecekler:
replayCounterfactual,ReplaySourceError,DEFAULT_SUITE,runSuite,checkScenariovenormalizeAnswer@gnldev/optimizer'dan@gnldev/experiment'e taşındı, takma ad yok; optimizer ile birlikte kurulur.compareOnSuitekalır. Bkz. optimizer.- Studio'nun Regression sekmesi,
POST /runs/:id/regressionveregressionModelseçeneği kaldırıldı; yerlerini Lab'ın capsule'ü alır (POST /lab/capsule, Inspector'ın Try in a capsule düğmesi). İki çalıştırmanın salt okunur farkı olanGET /runs/:id/regression/:otherIdkalır. - Lab'ın üç sekmesi var — Improve, New agent, Scenarios — ve dört mod ile
mode=capsulevemode=threadURL'leri kalktı. Bir şeyi değiştirilmiş capsule oyunu artık çalıştırmayı değiştirilmiş hâliyletrialskez, değiştirilmemiş hâliyletrialskez oynar, yani eskisinin yaklaşık iki katını harcar. - Hiçbir form tek bir senaryo çalıştırmasını geçmediyse
BestFormResult.bestyoktur ve hiçbir şey test etmeyen bir thread teşhisinot-founddeğiluntestedder. :memctxsayıları modele gönderileni anlatır ve:derived:bölümünü içeren bir run kimliği reddedilir. Bkz. Bellek.
@gnldev/lab deneyseldir; API'si değişecek.
API#
registerUpgradeStepsPaketlerin yükseltme adımlarını bir depoya ekler ve depoyu döndürür; depo kurulduğu yerde bir kez çağrılır. Hatalı bir kaydı, yükseltmenin ortasında bir şey patlamadan önce reddeder.
UpgradeFailedErrorBir adım hata verince storage.upgrade()'in fırlattığı hata: report (ne çalıştı) ve step, adımın kendi hatası cause olarak.
queueUpgraderegisterUpgradeSteps için kuyruğun adımları: queue/lanes, sonra queue/lanes-cleanup (afterOlderGone).
schedulerUpgradeZamanlayıcının adımı: scheduler/misfire-default (afterOlderGone), upgradeTriggers ile aynı taşıma.
upgradeTriggersSaklanan misfire 'skip' (0.16) değerini varsayılana yeniden yazar; dryRun neyi yapacağını listeler. Idempotent; her 0.16 poller'ı gidince bir kez çalıştırın.
markUpgradeDueBir paketin, deponun adımının henüz taşımadığı veri tuttuğunu bildiren notu; only verilmeyen upgrade() hiçbir kayıtlı adımın cevaplamadığı notu bildirir.