Buka konsol

Mencoba lagi fungsi asinkron

Dokumen ini menjelaskan cara meminta fungsi background asinkron (non-HTTPS) yang akan dicoba ulang saat terjadi kegagalan.

Semantik percobaan ulang

Cloud Functions menjamin paling tidak sekali eksekusi fungsi background untuk setiap peristiwa yang dipancarkan oleh sumber peristiwa. Namun, secara default, jika pemanggilan fungsi berhenti dengan pesan error, fungsi tersebut tidak akan dipanggil lagi, dan peristiwa akan dibatalkan. Saat Anda mengaktifkan percobaan ulang pada fungsi background, Cloud Functions akan mencoba kembali pemanggilan fungsi yang gagal hingga selesai dengan sukses, atau jendela percobaan ulang berakhir.

Penyebab fungsi background tidak dapat diselesaikan

Terkadang, fungsi keluar sebelum waktunya karena terjadi error internal, dan secara default fungsi tersebut akan atau tidak akan dicoba ulang secara otomatis.

Yang lebih umum lagi, fungsi background tidak dapat diselesaikan dengan baik karena terjadi error yang ditampilkan pada kode fungsi itu sendiri. Beberapa penyebabnya adalah sebagai berikut:

  • Fungsi berisi bug dan runtime menampilkan pengecualian.
  • Fungsi tidak dapat menjangkau endpoint layanan, atau waktu habis saat mencoba menjangkau endpoint.
  • Fungsi sengaja menampilkan pengecualian (misalnya, saat parameter menggagalkan validasi).
  • Ketika fungsi yang ditulis dalam Node.js menampilkan promise yang ditolak atau mengirimkan nilai bukan null ke callback.

Dalam kasus di atas, secara default fungsi akan berhenti dijalankan dan peristiwa itu akan dihapus. Jika ingin mencoba ulang fungsi ini ketika terjadi error, Anda dapat mengubah kebijakan percobaan ulang default dengan menyetel properti "coba ulang jika gagal". Dengan mengambil langkah ini, peristiwa akan dicoba ulang berkali-kali hingga beberapa hari sampai fungsi tersebut berhasil diselesaikan.

Mengaktifkan dan menonaktifkan percobaan ulang

Menggunakan Konsol GCP

Anda dapat mengaktifkan atau menonaktifkan percobaan ulang di Konsol GCP sebagai berikut:

  1. Buka halaman Ringkasan Cloud Functions di Cloud Platform Console.

  2. Klik Buat fungsi. Atau, klik fungsi yang ada untuk membuka halaman detailnya dan klik Edit.

  3. Lengkapi kolom wajib isi untuk fungsi Anda.

  4. Pastikan kolom Pemicu diatur ke jenis pemicu fungsi background, seperti Cloud Pub/Sub atau Cloud Storage.

  5. Perluas setelan lanjutan dengan mengklik Lainnya.

  6. Centang atau hapus centang pada kotak dengan label Coba lagi jika gagal.

Tips

Bagian ini menjelaskan praktik terbaik untuk menggunakan percobaan ulang.

Gunakan percobaan ulang untuk menangani error sementara

Karena fungsi terus dicoba ulang hingga berhasil dijalankan, error permanen, seperti bug, harus dihilangkan dari pengujian menyeluruh kode Anda sebelum percobaan ulang diaktifkan. Percobaan ulang paling baik digunakan untuk menangani kegagalan yang terputus-putus/sementara yang sangat mungkin akan teratasi melalui percobaan ulang, seperti endpoint layanan yang tidak stabil atau waktu tunggu habis.

Tetapkan condition akhir agar percobaan ulang tidak terjebak dalam pengulangan tanpa henti

Salah satu praktik terbaik adalah melindungi fungsi Anda dari pengulangan terus-menerus saat menggunakan percobaan ulang. Anda dapat melakukannya dengan menyertakan condition akhir yang ditetapkan dengan baik, sebelum fungsi mulai diproses. Pendekatan yang sederhana namun efektif adalah dengan menghapus peristiwa yang memiliki stempel waktu lebih lama dari rentang tertentu. Langkah ini dapat menghindari eksekusi berlebihan saat kegagalan terus-menerus terjadi atau berlangsung lebih lama daripada perkiraan.

Misalnya, cuplikan kode ini menghapus semua peristiwa yang lebih lama dari 10 detik:

const eventAgeMs = Date.now() - Date.parse(event.timestamp);
const eventMaxAgeMs = 10000;
if (eventAgeMs > eventMaxAgeMs) {
  console.log(`Dropping event ${event} with age[ms]: ${eventAgeMs}`);
  callback();
  return;
}

Gunakan catch dengan Promise

Jika Anda mengaktifkan percobaan ulang, pertimbangkan untuk menambahkan catch ke promise Anda. Cloud Functions tidak memahami error fatal yang seharusnya tidak dicoba ulang, sehingga Anda harus memodifikasi kode sebagaimana mestinya jika Anda mendukung error fatal.

Berikut adalah contoh tindakan yang sebaiknya Anda lakukan:

return doFooAsync().catch((err) => {
    if (isFatal(err)) {
        console.error(`Fatal error ${err}`);
    }
    return Promise.reject(err);
});

Idempoten-kan fungsi background yang dapat dicoba ulang

Fungsi background yang dapat dicoba ulang harus bersifat idempoten. Berikut ini beberapa panduan umum untuk membuat fungsi background menjadi idempoten:

  • Banyak API eksternal (seperti Stripe) yang dapat Anda gunakan untuk menyuplai kunci idempotensi sebagai parameter. Jika menggunakan API seperti itu, Anda harus menggunakan ID peristiwa sebagai kunci idempotensi.
  • Idempotensi berfungsi dengan baik pada pengiriman "setidaknya sekali" karena memberikan keamanan untuk mencoba ulang. Jadi, salah satu praktik terbaik yang umum untuk menulis kode tepercaya adalah dengan menggabungkan idempotensi dengan percobaan ulang.
  • Pastikan kode Anda idempoten secara internal. Misalnya:
    • Pastikan mutasi bisa terjadi lebih dari sekali tanpa mengubah hasilnya.
    • Jalankan kueri pada status database dalam transaksi sebelum memutasikan status tersebut.
    • Pastikan semua efek samping bersifat idempoten.
  • Lakukan pemeriksaan transaksi di luar fungsi, terlepas dari kode. Sebagai contoh, pertahankan status di suatu tempat yang mencatat bahwa ID peristiwa tertentu telah diproses.
  • Tangani panggilan fungsi duplikat yang tidak umum. Misalnya, jalankan proses pembersihan terpisah yang akan melakukan pembersihan setelah panggilan fungsi duplikat.