Saya ingin memberi tahu Anda bagaimana kami mengatur pembaruan data latar belakang selama permintaan ke layanan REST.
Tugasnya adalah sebagai berikut: sistem menyimpan data pengguna. Layanan ini bekerja secara terpisah dan tidak memiliki akses langsung ke database dengan data ini. Agar layanan dapat berfungsi, perlu untuk memiliki nama dan nama keluarga pengguna di basis data internal. Mereka dapat diperoleh dari Identitas pengguna saat ini pada saat permintaan. Diperlukan untuk menambah atau memperbarui nama selama setiap permintaan. Dianjurkan untuk menerapkan ini di utas terpisah sehingga pekerjaan ini tidak mempengaruhi waktu eksekusi permintaan utama.
Penyempurnaan tugas
Dalam basis data layanan, kami menyimpan nama dan nama keluarga pengguna. Pelanggan membutuhkan mereka untuk informasi tentang siapa yang membuat atau memodifikasi sumber daya.
Data ini tidak signifikan secara sistemik: jika tiba-tiba dalam database tidak ada catatan yang diperlukan, tidak ada hal buruk yang akan terjadi. Oleh karena itu, kami tidak ingin mendaftarkan pekerjaan latar belakang kami di ASP menggunakan QueueBackgroundWorkItem, untuk mempersulit pemuatan berlebih dari domain aplikasi.
Dianjurkan untuk memecahkan masalah sesederhana mungkin.
Bagi mereka yang ingin mempelajari lebih lanjut tentang tugas-tugas latar belakang di ASP.NET, saya menyarankan Anda untuk membaca
artikel yang bagus tentang hal itu.
Solusi
Kami memiliki kelas DbRefresher yang menambahkan atau mengubah data pengguna dalam metode RefreshAsync.
Pengontrol kami menggunakan atribut Otorisasi. Tambahkan keturunan kami ke kelas ini dan timpa metode OnAuthorization:
public override void OnAuthorization(HttpActionContext actionContext) { base.OnAuthorization(actionContext); if (IsAuthorized(actionContext)) DbRefresher.RefreshAsync(actionContext.RequestContext.Principal) .ContinueWith(t => { LogFactory.For<AuthorizeAndRefreshUserAttribute>() .ErrorException("Error occured", t.Exception); }, TaskContinuationOptions.OnlyOnFaulted); }
DbRefresher.RefreshAsync adalah metode asinkron yang mengembalikan objek tugas yang terus dieksekusi di utas lainnya. Metode OnAuthorize segera keluar tanpa menunggu tugas selesai. Jika terjadi kerusakan, pesan kesalahan akan ditambahkan ke log.
Itu saja: yang tersisa hanyalah mengganti atribut Otorisasi di controller dengan nama atribut baru kami. Atribut baru mengembalikan kontrol segera setelah memeriksa hak-hak pengguna saat ini, setelah itu controller mulai bekerja. Basis data akan diperbarui secara paralel dengan persiapan respons oleh pengontrol.
Pengujian
Tes yang menjalankan beberapa permintaan layanan simultan akan membantu mengidentifikasi kemungkinan masalah:
[TestMethod] public void ConcurrentTest() { const int threadCount = 10; var tasks = new Task[threadCount]; for (int i = 0; i < threadCount; i++) {
Masalahnya
Jika untuk pengoperasian beberapa metode tindakan dari pengontrol, diperlukan bahwa database jelas berisi data pengguna saat ini, pendekatan ini tidak cocok. Anda harus menggunakan panggilan eksplisit ke DbRefresher.RefreshAsync di badan metode.
Mungkin ada masalah saat menambahkan pengguna baru ke database dengan beberapa permintaan simultan. Jika ada upaya untuk menambahkan pengguna ke tabel dengan kunci yang ada, Anda harus menangkap pengecualian pelanggaran kunci utama dan berhenti bekerja. Kemudian semua pekerjaan memperbarui data pengguna akan dilakukan hanya dengan satu utas.
Kesimpulan
Pendekatan ini telah berhasil bekerja di salah satu layanan kami di Konfermit selama lebih dari setahun.
Bagiku sederhana dan elegan. Akan menarik untuk mengetahui pendapat masyarakat.