Topik temu duga representatif

Temu Bual Backend: Bagaimanakah Anda Mereka Bentuk Pipeline stream.compose Node.js yang Boleh Dibatalkan?

BackendSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Perkhidmatan Node.js mesti menstrim muat naik melalui penyahmampatan, pengimbasan, pengesahan dan storan objek. Bagaimanakah anda menjamin tekanan balik, pembatalan, penyebaran ralat dan pembersihan dengan stream.compose?

Gesaan dan konteks

Perkhidmatan Node.js menerima muat naik yang besar dan mesti menjalankan penyahmampatan, pengimbasan virus, pengesahan format, dan penulisan storan objek secara berurutan. Pelaksanaan lama mendengar peristiwa data secara manual, kadangkala meningkatkan penggunaan memori, terus berjalan selepas klien terputus sambungan, dan meninggalkan fail sementara apabila langkah perantaraan gagal.

Gunakan stream.compose() atau pendekatan komposisi pipeline yang setara. Terangkan cara peringkat readable, writable, dan Transform disambungkan, dan bagaimana tekanan balik, AbortSignal, penyebaran ralat, serta pembersihan akhir memastikan satu kerja kekal terkawal.

Perkara yang diuji oleh penemu bual

  • Sama ada anda membezakan sempadan dan kitaran hayat pipe, pipeline, dan compose.
  • Sama ada anda boleh menerangkan cara tekanan balik mengehadkan pengeluaran dan bukannya sekadar meningkatkan had giliran.
  • Sama ada pembatalan, pengecualian dan pemutusan sambungan klien tersebar melalui keseluruhan pipeline.
  • Sama ada anda mengendalikan penjana tak segerak (async generator), pelepasan sumber, penulisan idempoten dan kebolehmerhatian.

Soalan untuk penjelasan

  1. Adakah input datang daripada permintaan HTTP, fail, atau SDK storan objek? Adakah output multipart dan percubaan semula disokong?
  2. Adakah setiap peringkat merupakan strim Node, Web Stream, AsyncIterable, atau fungsi biasa?
  3. Adakah pengimbasan dan pengesahan mencipta proses anak (child process), fail sementara, atau keadaan pangkalan data?
  4. Bolehkah storan objek membatalkan muat naik multipart, dan adakah kerja yang dibatalkan mesti disambung semula?

Jawapan 30 saat

Saya akan mentakrifkan setiap peringkat sebagai readable, writable, Transform, atau AsyncIterable dan menggabungkannya ke dalam Duplex dengan stream.compose(), kemudian membiarkan pipeline memacu destinasi akhir. Pengeluar hanya meneruskan apabila bahagian hiliran (downstream) boleh menerima data, jadi tekanan balik mengehadkan penggunaan memori. Pemutusan sambungan permintaan, had masa (deadline), dan pembatalan perniagaan berkongsi satu AbortSignal yang dihantar ke peringkat yang disokong; sebarang ralat akan menggagalkan keseluruhan rantaian. Fail sementara, proses anak dan muat naik multipart dibersihkan dalam pengendali finally atau abort, dan penulisan menggunakan kunci keidempotennan. Metrik meliputi daya pemprosesan (throughput), kedalaman giliran, puncak RSS, sebab pembatalan dan hasil pembersihan.

Pecahan terperinci langkah demi langkah

Tentukan kontrak setiap peringkat

Nyatakan jenis input dan output, saiz ketulan (chunk), sama ada null dibenarkan, tingkah laku penyekatan, dan pemilikan sumber apabila selesai. Penjana tak segerak mesti menggunakan sumbernya dan menghasilkan (yield) mengikut permintaan; fungsi biasa tidak boleh membaca keseluruhan fail ke dalam memori secara senyap.

Gubah peringkat yang boleh diguna semula

compose menyambungkan strim, AsyncIterable, atau fungsi ke dalam Duplex baharu dan mengendalikan peringkat bersebelahan dengan semantik pipeline. Contoh:

js
import { compose } from 'node:stream';

async function* validate(source) {
  for await (const chunk of source) {
    checkChunk(chunk);
    yield chunk;
  }
}

const processing = compose(decompress(), validate, scan());

Pelaksanaan sebenar mesti menyambungkan pemprosesan ke writable destinasi dan memusatkan penyelesaian serta ralat dan bukannya menelannya pada setiap peringkat.

Jadikan tekanan balik sebagai satah kawalan lalai

Apabila bahagian hiliran belum bersedia, peringkat Readable dan Transform harus berhenti mengeluarkan data. Jangan tolak tanpa had dalam panggilan balik data atau menyembunyikan pengguna yang perlahan dengan menaikkan paras tanda air tinggi (high-water mark) tanpa henti. Ujian beban harus merekodkan setiap giliran, daya pemprosesan, dan RSS supaya peringkat paling perlahan menentukan kelajuan keseluruhan.

Sebarkan pembatalan dan pemutusan sambungan

Gabungkan pemutusan sambungan permintaan, had masa, dan pembatalan manual dalam satu AbortController. Hantarkan isyaratnya ke peringkat compose yang disokong dan SDK luaran; selepas pembatalan, hentikan pembacaan, musnahkan (destroy) hiliran, dan tunggu penutupan. Log mesti membezakan antara pembatalan biasa, kegagalan perniagaan, dan ralat rangkaian.

Pusatkan ralat dan pembersihan

Satu pemilik harus memanggil pipeline/compose, menerima ralat pertama, dan memusnahkan rantaian tersebut. Fail sementara, pengimbas, soket dan muat naik multipart mesti dilepaskan semasa kejayaan, kegagalan dan pembatalan; kegagalan pembersihan memberi amaran bersama ID kerja tanpa menggantikan ralat asal.

Reka bentuk keidempotennan dan metrik

Hasilkan kunci keidempotennan daripada ID muat naik dan versi peringkat, kemudian komit keadaan perniagaan hanya selepas penulisan objek selesai. Rekodkan bait input dan output, tempoh, puncak RSS, sebab pembatalan, peringkat yang gagal dan masa pembersihan. Cuba semula hanya dari sempadan yang boleh dipulihkan untuk mengelakkan penulisan pendua.

Jawapan model

Saya akan mentakrifkan muat naik, penyahmampatan, pengimbasan, pengesahan, dan storan sebagai peringkat dengan input, output dan pemilikan yang eksplisit, menggabungkannya ke dalam pipeline readable, writable, atau async-iterable, dan membiarkan satu pemilik pipeline memacunya. Penggunaan hiliran mengawal tekanan balik; penimbalan tanpa had dalam pengendali data adalah dilarang. Pemutusan sambungan, tamat masa dan pembatalan manual berkongsi AbortSignal yang dihantar ke peringkat yang disokong dan SDK storan. Pemilik mengendalikan ralat pertama dan memusnahkan rantaian; fail sementara, pengimbas dan muat naik multipart dibersihkan semasa kejayaan, kegagalan dan pembatalan. Kunci keidempotennan melindungi penulisan, metrik meliputi daya pemprosesan, giliran, RSS, pembatalan dan pembersihan, serta percubaan semula bermula hanya pada sempadan yang selamat.

Kesilapan lazim

  • Mengumpul keseluruhan strim ke dalam Buffer dan masih mendakwa menggunakan compose.
  • Hanya mendengar error writable akhir, terlepas kegagalan async-generator atau proses anak.
  • Terus membaca dan menulis selepas klien terputus sambungan.
  • Menyelesaikan tekanan balik dengan meningkatkan tanda air tinggi secara berterusan tanpa had.
  • Memadam fail sementara hanya apabila berjaya, mengabaikan pembatalan dan pengecualian.
  • Mencuba semula tanpa kunci keidempotennan dan menduplikasi objek atau keadaan perniagaan.

Soalan susulan

Apakah perbezaan antara compose dan pipeline?

Compose mencipta Duplex yang boleh diguna semula daripada peringkat-peringkat; pipeline memacu sambungan dari hujung ke hujung, menyebarkan ralat, dan menunggu penutupan. Ia boleh digabungkan, tetapi pemilikan dan pengendalian ralat harus dipusatkan.

Apakah yang berlaku apabila penjana tak segerak melontarkan ralat?

Strim yang digubah harus gagal dan memusnahkan peringkat bersebelahan. Pemanggil masih menunggu pembersihan pipeline dan merekodkan peringkat yang gagal daripada hanya bergantung pada penamatan proses.

Bagaimanakah anda mengesahkan bahawa tekanan balik berfungsi?

Uji beban dengan pengeluar yang lebih pantas daripada sink perlahan yang terkawal, perhatikan kedalaman giliran dan RSS yang terhad, dan sahkan bahawa daya pemprosesan mengikut peringkat paling perlahan dan bukannya penimbalan tanpa had.

Bolehkah anda mencuba semula serta-merta selepas pembatalan?

Mula-mula sahkan bahawa semua sumber ditutup dan keadaan sementara boleh dikenal pasti. Cuba semula dari sempadan yang boleh dipulihkan dan idempoten; berikan pampasan atau tandakan keadaan yang tidak diketahui untuk penulisan luaran yang tidak boleh diganggu.

Sumber awam

Soalan berkaitan