Eksekusi SDK yang tahan lama - AWS Lambda

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Eksekusi SDK yang tahan lama

SDK eksekusi yang tahan lama adalah fondasi untuk membangun fungsi yang tahan lama. Ini menyediakan primitif yang Anda butuhkan untuk memeriksa kemajuan, menangani percobaan ulang, dan mengelola alur eksekusi. SDK mengabstraksi kompleksitas manajemen pos pemeriksaan dan pemutaran ulang, memungkinkan Anda menulis kode sekuensial yang secara otomatis menjadi toleran terhadap kesalahan.

SDK tersedia untuk JavaScript, TypeScript, dan Python. Untuk dokumentasi dan contoh API lengkap, lihat SDK JavaScript/TypeScript SDK dan Python aktif. GitHub

DurableContext

SDK menyediakan fungsi Anda dengan DurableContext objek yang mengekspos semua operasi tahan lama. Konteks ini menggantikan konteks Lambda standar dan menyediakan metode untuk membuat pos pemeriksaan, mengelola alur eksekusi, dan berkoordinasi dengan sistem eksternal.

Untuk menggunakan SDK, bungkus handler Lambda Anda dengan pembungkus eksekusi yang tahan lama:

TypeScript
import { withDurableExecution, DurableContext } from '@aws/durable-execution-sdk-js'; export const handler = withDurableExecution( async (event: any, context: DurableContext) => { // Your function receives DurableContext instead of Lambda context // Use context.step(), context.wait(), etc. return result; } );
Python
from aws_durable_execution_sdk_python import durable_execution, DurableContext @durable_execution def handler(event: dict, context: DurableContext): # Your function receives DurableContext # Use context.step(), context.wait(), etc. return result

Pembungkus mencegat pemanggilan fungsi Anda, memuat log pos pemeriksaan yang ada, dan menyediakan yang mengelola pemutaran ulang dan pos pemeriksaan. DurableContext

Apa yang dilakukan SDK

SDK menangani tiga tanggung jawab penting yang memungkinkan eksekusi yang tahan lama:

Manajemen pos pemeriksaan: SDK secara otomatis membuat pos pemeriksaan saat fungsi Anda menjalankan operasi yang tahan lama. Setiap pos pemeriksaan mencatat jenis operasi, input, dan hasil. Saat fungsi Anda menyelesaikan langkah, SDK akan tetap berada di pos pemeriksaan sebelum melanjutkan. Ini memastikan fungsi Anda dapat dilanjutkan dari operasi yang selesai jika terputus.

Koordinasi pemutaran ulang: Saat fungsi Anda dilanjutkan setelah jeda atau interupsi, SDK akan melakukan pemutaran ulang. Ini menjalankan kode Anda dari awal tetapi melewatkan operasi yang telah selesai, menggunakan hasil pos pemeriksaan yang disimpan alih-alih mengeksekusinya kembali. SDK memastikan pemutaran ulang bersifat deterministik—dengan input dan log pos pemeriksaan yang sama, fungsi Anda menghasilkan hasil yang sama.

Isolasi status: SDK mempertahankan status eksekusi secara terpisah dari logika bisnis Anda. Setiap eksekusi tahan lama memiliki log pos pemeriksaan sendiri yang tidak dapat diakses oleh eksekusi lain. SDK mengenkripsi data pos pemeriksaan saat istirahat dan memastikan status tetap konsisten di seluruh pemutaran ulang.

Cara kerja checkpointing

Saat Anda memanggil operasi yang tahan lama, SDK mengikuti urutan ini:

  1. Periksa pos pemeriksaan yang ada: SDK memeriksa apakah operasi ini sudah selesai dalam pemanggilan sebelumnya. Jika pos pemeriksaan ada, SDK mengembalikan hasil yang disimpan tanpa mengeksekusi ulang operasi.

  2. Jalankan operasi: Jika tidak ada pos pemeriksaan, SDK mengeksekusi kode operasi Anda. Untuk langkah-langkah, ini berarti memanggil fungsi Anda. Untuk menunggu, ini berarti penjadwalan dimulainya kembali.

  3. Buat pos pemeriksaan: Setelah operasi selesai, SDK membuat serial hasilnya dan membuat pos pemeriksaan. Pos pemeriksaan mencakup jenis operasi, nama, input, hasil, dan stempel waktu.

  4. Persistent checkpoint: SDK memanggil API pos pemeriksaan Lambda untuk mempertahankan pos pemeriksaan. Ini memastikan pos pemeriksaan tahan lama sebelum melanjutkan eksekusi.

  5. Hasil pengembalian: SDK mengembalikan hasil operasi ke kode Anda, yang berlanjut ke operasi berikutnya.

Urutan ini memastikan bahwa setelah operasi selesai, hasilnya disimpan dengan aman. Jika fungsi Anda terganggu pada titik mana pun, SDK dapat memutar ulang hingga pos pemeriksaan terakhir yang diselesaikan.

Perilaku memutar ulang

Saat fungsi Anda dilanjutkan setelah jeda atau interupsi, SDK akan melakukan pemutaran ulang:

  1. Muat log pos pemeriksaan: SDK mengambil log pos pemeriksaan untuk eksekusi ini dari Lambda.

  2. Jalankan dari awal: SDK memanggil fungsi handler Anda dari awal, bukan dari tempat dijeda.

  3. Lewati operasi tahan lama yang telah selesai: Saat kode Anda memanggil operasi yang tahan lama, SDK memeriksa masing-masing terhadap log pos pemeriksaan. Untuk operasi tahan lama yang selesai, SDK mengembalikan hasil yang disimpan tanpa mengeksekusi kode operasi.

    catatan

    Jika hasil konteks anak lebih besar dari ukuran pos pemeriksaan maksimum (256 KB), kode konteks dieksekusi lagi selama pemutaran ulang. Ini memungkinkan Anda untuk membuat hasil besar dari operasi tahan lama yang berjalan di dalam konteks, yang akan dicari dari log pos pemeriksaan. Oleh karena itu sangat penting untuk hanya menjalankan kode deterministik dalam konteks itu sendiri. Saat menggunakan konteks anak dengan hasil yang besar, ini adalah praktik terbaik untuk melakukan pekerjaan jangka panjang atau non-deterministik di dalam langkah-langkah dan hanya melakukan tugas jangka pendek yang menggabungkan hasil dalam konteks itu sendiri.

  4. Lanjutkan pada titik interupsi: Ketika SDK mencapai operasi tanpa pos pemeriksaan, SDK dijalankan secara normal dan membuat pos pemeriksaan baru saat operasi tahan lama selesai.

Mekanisme replay ini mengharuskan kode Anda menjadi deterministik. Dengan input dan log pos pemeriksaan yang sama, fungsi Anda harus membuat urutan panggilan operasi tahan lama yang sama. SDK memberlakukan ini dengan memvalidasi bahwa nama dan jenis operasi cocok dengan log pos pemeriksaan selama pemutaran ulang.

Tersedia operasi tahan lama

DurableContextMenyediakan operasi untuk pola koordinasi yang berbeda. Setiap operasi yang tahan lama membuat pos pemeriksaan secara otomatis, memastikan fungsi Anda dapat dilanjutkan dari titik mana pun.

Langkah-langkah

Menjalankan logika bisnis dengan checkpointing otomatis dan coba lagi. Gunakan langkah-langkah untuk operasi yang memanggil layanan eksternal, melakukan perhitungan, atau menjalankan logika apa pun yang harus diperiksa. SDK membuat pos pemeriksaan sebelum dan sesudah langkah, menyimpan hasilnya untuk diputar ulang.

TypeScript
const result = await context.step('process-payment', async () => { return await paymentService.charge(amount); });
Python
result = context.step( lambda _: payment_service.charge(amount), name='process-payment' )

Langkah-langkah mendukung strategi coba ulang yang dapat dikonfigurasi, semantik eksekusi (at-most-once atau at-least-once), dan serialisasi kustom.

Tunggu

Menjeda eksekusi untuk durasi tertentu tanpa menggunakan sumber daya komputasi. SDK membuat pos pemeriksaan, menghentikan pemanggilan fungsi, dan menjadwalkan dimulainya kembali. Ketika menunggu selesai, Lambda memanggil fungsi Anda lagi dan SDK diputar ulang ke titik tunggu sebelum melanjutkan.

TypeScript
// Wait 1 hour without charges await context.wait({ seconds: 3600 });
Python
# Wait 1 hour without charges context.wait(3600)

Callback

Callback memungkinkan fungsi Anda berhenti sejenak dan menunggu sistem eksternal memberikan masukan. Saat Anda membuat callback, SDK akan menghasilkan ID callback unik dan membuat pos pemeriksaan. Fungsi Anda kemudian ditangguhkan (menghentikan pemanggilan) tanpa menimbulkan biaya komputasi. Sistem eksternal mengirimkan hasil callback menggunakan SendDurableExecutionCallbackSuccess atau SendDurableExecutionCallbackFailure Lambda APIs. Saat callback dikirimkan, Lambda akan memanggil fungsi Anda lagi, SDK akan diputar ulang ke titik callback, dan fungsi Anda berlanjut dengan hasil callback.

SDK menyediakan dua metode untuk bekerja dengan callback:

createCallback: Membuat callback dan mengembalikan janji dan ID callback. Anda mengirim ID callback ke sistem eksternal, yang mengirimkan hasilnya menggunakan API Lambda.

TypeScript
const [promise, callbackId] = await context.createCallback('approval', { timeout: { hours: 24 } }); await sendApprovalRequest(callbackId, requestData); const approval = await promise;
Python
callback = context.create_callback( name='approval', config=CallbackConfig(timeout_seconds=86400) ) context.step( lambda _: send_approval_request(callback.callback_id), name='send_request' ) approval = callback.result()

waitForCallback: Menyederhanakan penanganan callback dengan menggabungkan pembuatan callback dan pengiriman dalam satu operasi. SDK membuat callback, mengeksekusi fungsi submitter Anda dengan ID callback, dan menunggu hasilnya.

TypeScript
const result = await context.waitForCallback( 'external-api', async (callbackId, ctx) => { await submitToExternalAPI(callbackId, requestData); }, { timeout: { minutes: 30 } } );
Python
result = context.wait_for_callback( lambda callback_id: submit_to_external_api(callback_id, request_data), name='external-api', config=WaitForCallbackConfig(timeout_seconds=1800) )

Konfigurasikan batas waktu untuk mencegah fungsi menunggu tanpa batas waktu. Jika waktu panggilan balik habis, SDK akan melempar a CallbackError dan fungsi Anda dapat menangani kasus batas waktu. Gunakan batas waktu detak jantung untuk panggilan balik yang berjalan lama untuk mendeteksi kapan sistem eksternal berhenti merespons.

Gunakan callback untuk human-in-the-loop alur kerja, integrasi sistem eksternal, respons webhook, atau skenario apa pun di mana eksekusi harus dijeda untuk input eksternal.

Eksekusi paralel

Menjalankan beberapa operasi bersamaan dengan kontrol konkurensi opsional. SDK mengelola eksekusi paralel, membuat pos pemeriksaan untuk setiap operasi, dan menangani kegagalan sesuai dengan kebijakan penyelesaian Anda.

TypeScript
const results = await context.parallel([ async (ctx) => ctx.step('task1', async () => processTask1()), async (ctx) => ctx.step('task2', async () => processTask2()), async (ctx) => ctx.step('task3', async () => processTask3()) ]);
Python
results = context.parallel( lambda ctx: ctx.step(lambda _: process_task1(), name='task1'), lambda ctx: ctx.step(lambda _: process_task2(), name='task2'), lambda ctx: ctx.step(lambda _: process_task3(), name='task3') )

Gunakan parallel untuk menjalankan operasi independen secara bersamaan.

Peta

Secara bersamaan menjalankan operasi pada setiap item dalam array dengan kontrol konkurensi opsional. SDK mengelola eksekusi bersamaan, membuat pos pemeriksaan untuk setiap operasi, dan menangani kegagalan sesuai dengan kebijakan penyelesaian Anda.

TypeScript
const results = await context.map(itemArray, async (ctx, item, index) => ctx.step('task', async () => processItem(item, index)) );
Python
results = context.map( item_array, lambda ctx, item, index: ctx.step( lambda _: process_item(item, index), name='task' ) )

Gunakan map untuk memproses array dengan kontrol konkurensi.

Konteks anak

Menciptakan konteks eksekusi terisolasi untuk operasi pengelompokan. Konteks anak memiliki log pos pemeriksaan sendiri dan dapat berisi beberapa langkah, menunggu, dan operasi lainnya. SDK memperlakukan seluruh konteks anak sebagai satu unit untuk coba lagi dan pemulihan.

Gunakan konteks anak untuk mengatur alur kerja yang kompleks, mengimplementasikan sub-alur kerja, atau mengisolasi operasi yang harus dicoba lagi bersama-sama.

TypeScript
const result = await context.runInChildContext( 'batch-processing', async (childCtx) => { return await processBatch(childCtx, items); } );
Python
result = context.run_in_child_context( lambda child_ctx: process_batch(child_ctx, items), name='batch-processing' )

Mekanisme replay menuntut agar operasi yang tahan lama terjadi dalam urutan deterministik. Dengan menggunakan beberapa konteks anak, Anda dapat menjalankan beberapa aliran pekerjaan secara bersamaan, dan determinisme berlaku secara terpisah dalam setiap konteks. Ini memungkinkan Anda untuk membangun fungsi kinerja tinggi yang secara efisien memanfaatkan beberapa core CPU.

Misalnya, bayangkan kita memulai dua konteks anak, A dan B. Pada pemanggilan awal, langkah-langkah dalam konteks dijalankan dalam urutan ini, dengan langkah 'A' berjalan bersamaan dengan langkah 'B': A1, B1, B2, A2, A3. Setelah diputar ulang, waktunya jauh lebih cepat karena hasil diambil dari log pos pemeriksaan, dan langkah-langkahnya ditemukan dalam urutan yang berbeda: B1, A1, A2, B2, A3. Karena langkah 'A' ditemui dalam urutan yang benar (A1, A2, A3) dan langkah 'B' ditemui dalam urutan yang benar (B1, B2), kebutuhan akan determinisme dipenuhi dengan benar.

Penantian bersyarat

Jajak pendapat untuk kondisi dengan pos pemeriksaan otomatis di antara upaya. SDK mengeksekusi fungsi pemeriksaan Anda, membuat pos pemeriksaan dengan hasilnya, menunggu sesuai dengan strategi Anda, dan mengulangi hingga kondisi terpenuhi.

TypeScript
const result = await context.waitForCondition( async (state, ctx) => { const status = await checkJobStatus(state.jobId); return { ...state, status }; }, { initialState: { jobId: 'job-123', status: 'pending' }, waitStrategy: (state) => state.status === 'completed' ? { shouldContinue: false } : { shouldContinue: true, delay: { seconds: 30 } } } );
Python
result = context.wait_for_condition( lambda state, ctx: check_job_status(state['jobId']), config=WaitForConditionConfig( initial_state={'jobId': 'job-123', 'status': 'pending'}, wait_strategy=lambda state, attempt: {'should_continue': False} if state['status'] == 'completed' else {'should_continue': True, 'delay': 30} ) )

Gunakan waitForCondition untuk polling sistem eksternal, menunggu sumber daya siap, atau menerapkan coba lagi dengan backoff.

Pemanggilan fungsi

Memanggil fungsi Lambda lain dan menunggu hasilnya. SDK membuat pos pemeriksaan, memanggil fungsi target, dan melanjutkan fungsi Anda saat pemanggilan selesai. Hal ini memungkinkan komposisi fungsi dan dekomposisi alur kerja.

TypeScript
const result = await context.invoke( 'invoke-processor', 'arn:aws:lambda:us-east-1:123456789012:function:processor', { data: inputData } );
Python
result = context.invoke( 'arn:aws:lambda:us-east-1:123456789012:function:processor', {'data': input_data}, name='invoke-processor' )

Bagaimana operasi yang tahan lama diukur

Setiap operasi tahan lama yang Anda panggil DurableContext membuat pos pemeriksaan untuk melacak kemajuan eksekusi dan menyimpan data status. Operasi ini dikenakan biaya berdasarkan penggunaannya, dan pos pemeriksaan mungkin berisi data yang berkontribusi pada biaya penulisan dan penyimpanan data Anda. Data yang disimpan mencakup data peristiwa pemanggilan, muatan yang dikembalikan dari langkah, dan data yang diteruskan saat menyelesaikan panggilan balik. Memahami bagaimana operasi tahan lama diukur membantu Anda memperkirakan biaya eksekusi dan mengoptimalkan alur kerja Anda. Untuk detail tentang harga, lihat halaman harga Lambda.

Ukuran muatan mengacu pada ukuran data serial yang tetap ada operasi yang tahan lama. Data diukur dalam byte dan ukurannya dapat bervariasi tergantung pada serializer yang digunakan oleh operasi. Muatan operasi bisa menjadi hasil itu sendiri untuk penyelesaian yang berhasil, atau objek kesalahan serial jika operasi gagal.

Operasi dasar

Operasi dasar adalah blok bangunan mendasar untuk fungsi tahan lama:

Operasi Waktu pos pemeriksaan Jumlah operasi Data bertahan
Eksekusi Dimulai 1 Ukuran muatan masukan
Eksekusi Selesai (Succeeded/Failed/Stopped) 0 Ukuran muatan keluaran
Langkah Retry/Succeeded/Failed 1 + N mencoba lagi Ukuran payload yang dikembalikan dari setiap upaya
Tunggu Dimulai 1 N/A
WaitForCondition Setiap upaya jajak pendapat 1 + N jajak pendapat Ukuran payload yang dikembalikan dari setiap upaya jajak pendapat
Coba Ulang Tingkat Permintaan Dimulai 1 Muatan untuk objek kesalahan

Operasi callback

Operasi callback memungkinkan fungsi Anda berhenti sejenak dan menunggu sistem eksternal memberikan masukan. Operasi ini membuat pos pemeriksaan saat callback dibuat dan saat selesai:

Operasi Waktu pos pemeriksaan Jumlah operasi Data bertahan
CreateCallback Dimulai 1 N/A
Penyelesaian panggilan balik melalui panggilan API Selesai 0 Payload panggilan balik
WaitForCallback Dimulai 3 + N mencoba ulang (konteks+panggilan balik+langkah) Muatan yang dikembalikan oleh upaya langkah pengirim, ditambah dua salinan payload callback

Operasi majemuk

Operasi gabungan menggabungkan beberapa operasi tahan lama untuk menangani pola koordinasi yang kompleks seperti eksekusi paralel, pemrosesan array, dan konteks bersarang:

Operasi Waktu pos pemeriksaan Jumlah operasi Data bertahan
Paralel Dimulai 1 + N cabang (1 konteks orangtua+N konteks anak) Hingga dua salinan ukuran muatan yang dikembalikan dari setiap cabang, ditambah status masing-masing cabang
Peta Dimulai 1 + N cabang (1 konteks orangtua+N konteks anak) Hingga dua salinan ukuran payload yang dikembalikan dari setiap iterasi, ditambah status setiap iterasi
Menjanjikan pembantu Selesai 1 Ukuran payload yang dikembalikan dari janji
RunInChildContext Berhasil/Gagal 1 Ukuran payload yang dikembalikan dari konteks anak

Untuk konteks, seperti dari runInChildContext atau digunakan secara internal oleh operasi gabungan, hasil yang lebih kecil dari 256 KB diperiksa secara langsung. Hasil yang lebih besar tidak disimpan — sebaliknya, mereka direkonstruksi selama pemutaran ulang dengan memproses ulang operasi konteks.