Bagaimana menerapkan manajer proses dalam sumber acara


14

Saya sedang mengerjakan contoh aplikasi kecil untuk mempelajari konsep CQRS dan event sourcing. Saya memiliki Basketagregat dan Productagregat yang harus bekerja secara independen.

Berikut beberapa kode semu untuk menunjukkan implementasinya

Basket { BasketId; OrderLines; Address; }

// basket events
BasketCreated { BasketId; }
ItemAdded { BasketId; ProductId; Quantity }
AddItemSucceeded { BasketId; ProductId; Quantity }
AddItemRevoked { BasketId; ProductId; Quantity }
ItemRemoved { BasketId; ProductId; Quantity }
CheckedOut { BasketId; Address }

Product { ProductId; Name; Price; }

// product events
ProductReserved { ProductId; Quantity }
ProductReservationFailed { ProductId; Quantity }
ProductReservationCancelled { ProductId; Quantity; }

Perintah sangat mirip dengan acara, menggunakan nama imperatif dan bukan lampau.

Sekarang ini bekerja dengan baik secara mandiri. Saya mengeluarkan perintah AddItem, dan itu menciptakan ItemAddedacara pada Basketagregat yang melakukan apa yang perlu dilakukan dengan keadaan 'Keranjang'. Demikian pula, untuk produk, perintah dan acara berfungsi dengan baik.

Sekarang saya ingin menggabungkan ini ke dalam proses yang akan berjalan seperti ini (dalam hal perintah dan peristiwa yang terjadi):

Manajer proses akan melakukan hal berikut:

on BasketCreated: CreateShoppingProcess
on ItemAdded: ReserveProduct
on ProductReserved: SucceedAddingItem // does nothing, but needs to be there so that the basket knows it can check out
on ProductReservationFailed: RevokeAddItem
on RemoveItem: CancelProductReservation
on Checkout: CreateOrder // create an order and so on...

Pertanyaan yang saya tidak dapat menemukan jawaban pasti adalah:

  1. Apakah saya perlu bertahan pada manajer proses? Sepertinya saya lakukan, tetapi saya tidak yakin
  2. Jika saya melakukannya, saya harus menyimpan acara untuk manajer proses. Namun, peristiwa yang didengarnya terkait dengan kelompok unsur kehidupan. Apakah saya menambahkan id proses itu? Apakah saya memiliki acara terpisah hanya untuk manajer proses? Cara melakukan ini dan tetap KERING mungkin
  3. Bagaimana saya tahu untuk apa keranjang ProductReservedacara? Apakah boleh menggunakan BasketIditu juga, atau apakah itu info yang bocor?
  4. Bagaimana saya menjaga hubungan antara acara, bagaimana saya tahu yang ItemAddedmenghasilkan ProductReservedacara yang mana ? Apakah saya melewati sebuah EventId? Ini sepertinya aneh ...
  5. Haruskah saya menerapkan Basketsebagai manajer proses daripada agregat sederhana?

Setelah beberapa penelitian lebih lanjut saya datang ke ini: Saga adalah sesuatu yang membuat acara sendiri dan mendengarkan acara dari luar. Pada dasarnya, ini adalah Agregat yang juga dapat bereaksi terhadap peristiwa yang terjadi di luar dunia kecil itu sendiri.

Seorang Manajer Proses bekerja dengan peristiwa dari luar dan mengirimkan perintah. Riwayatnya dapat dibangun kembali dari peristiwa yang terjadi pada Agregat yang berbagi pengidentifikasi umum seperti korelasiId.


Tampaknya Anda mencoba untuk menyandikan dalam sistem Anda proses formal yang memparafrasekan kasus penggunaan informal yang ada yang dibuat dari serangkaian perintah. Melakukan itu, sepertinya Anda membuat sejumlah perintah dan acara yang berlebihan selain yang sudah ada. Apakah itu niat Anda? Apa yang dibutuhkan bisnis di balik memformalkan hal-hal sebagai proses dalam kode? Apa dalam domain Anda yang mengharuskan Anda mengidentifikasi proses dan alasannya sebagai konsep yang lengkap?
guillaume31

Ini adalah proyek yang sepenuhnya dibuat di mana tujuannya adalah untuk belajar bagaimana membuat dua agregat yang relatif independen bekerja bersama. Jadi benar-benar tidak ada "kebutuhan bisnis" yang nyata, dan saya berusaha untuk menghindari redundansi dalam perintah dan acara ini sebanyak mungkin. Oleh karena itu kebingungan dengan manajer proses., Karena tampaknya tidak boleh mengulangi hal-hal yang sudah ditangani oleh agregat. Namun, saya harus menjaga koneksi antara kedua kelompok ini. Tampaknya menggunakan sebab-akibat dan korelasi mungkin membantu, tetapi saya perlu mencobanya.
Ivan Pintar

Jawaban:


14

Tinjau apa yang ditulis Rinat Abdullin tentang proses bisnis yang berkembang . Secara khusus, perhatikan rekomendasinya untuk mengembangkan proses bisnis di lingkungan yang berubah cepat - seorang manajer proses adalah "hanya" pengganti otomatis bagi manusia yang menatap layar.

Model mental saya sendiri dari seorang manajer proses adalah bahwa ini merupakan proyeksi yang bersumber dari peristiwa yang dapat Anda query untuk daftar perintah yang tertunda.

Apakah saya perlu bertahan pada manajer proses? Sepertinya saya lakukan, tetapi saya tidak yakin

Ini model baca. Anda dapat membangun kembali manajer proses dari sejarah acara setiap kali Anda membutuhkannya; atau Anda dapat memperlakukannya seperti snapshot yang Anda perbarui.

Jika saya melakukannya, saya harus menyimpan acara untuk manajer proses.

Tidak - manajer proses adalah manajer . Itu tidak melakukan sesuatu yang berguna dengan sendirinya; alih-alih itu memberitahu agregat untuk melakukan pekerjaan (yaitu, membuat perubahan pada buku catatan).

Bagaimana saya tahu keranjang apa yang digunakan untuk acara ProductReserved? Apakah OK untuk memiliki BasketID juga, atau informasi bocor

Tentu. Catatan: di sebagian besar domain belanja "nyata", Anda tidak akan memaksa memesan inventaris sebelum memproses pesanan; itu menambah pertengkaran yang tidak perlu terhadap bisnis. Kemungkinan besar bisnis Anda ingin menerima pesanan, lalu meminta maaf dalam kasus langka bahwa pesanan tidak dapat dipenuhi pada waktu yang diperlukan.

Bagaimana cara menjaga hubungan antara acara, bagaimana saya tahu ItemAdded mana yang menghasilkan acara ProductReserved?

Pesan memiliki data meta - khususnya, Anda dapat menyertakan causationIdentifier (sehingga Anda dapat mengidentifikasi perintah mana yang menghasilkan peristiwa mana) dan korelasi , untuk melacak percakapan secara umum.

Sebagai contoh, manajer proses menulis id sendiri sebagai korelasiId dalam perintah; peristiwa yang dihasilkan oleh salinan id korelasi dari perintah, dan manajer proses Anda berlangganan semua peristiwa yang memiliki korelasi sendiri.

Haruskah saya menerapkan Keranjang sebagai manajer proses alih-alih agregat sederhana?

Rekomendasi saya adalah tidak. Tetapi Udi Dahan memiliki pendapat berbeda yang harus Anda tinjau; yaitu bahwa CQRS hanya masuk akal jika agregat Anda adalah kisah-kisah - Udi menggunakan kisah di tempat manajer proses telah menjadi ejaan dominan.

haruskah manajer proses mengambil agregat?

Tidak juga? Manajer proses terutama berkaitan dengan orkestrasi, bukan keadaan domain. Sebuah instance dari suatu proses akan memiliki "keadaan", dalam bentuk sejarah dari semua peristiwa yang telah mereka amati - hal yang benar untuk dilakukan dalam menanggapi peristiwa Z tergantung pada apakah kita telah melihat peristiwa X dan Y atau tidak. Jadi, Anda mungkin harus dapat menyimpan dan memuat representasi negara itu (yang bisa menjadi sesuatu yang datar, atau bisa menjadi sejarah peristiwa yang diamati).

(Saya mengatakan "tidak benar-benar" karena agregat didefinisikan secara samar-samar sehingga tidak sepenuhnya salah untuk mengklaim bahwa daftar peristiwa yang diamati adalah "agregat". Perbedaannya lebih semantik daripada implementasi - kami memuat status proses dan kemudian memutuskan pesan yang akan dikirim ke kirim ke bagian-bagian sistem yang bertanggung jawab atas status domain . Ada sedikit lambaian tangan di sini.)

Jadi PM tidak perlu menggunakan satu jenis manajemen negara lebih dari yang lain karena hanya bertanggung jawab untuk melakukan pekerjaan langsung dan tidak pernah selama replay?

Tidak cukup - manajemen negara bukan pelaku, ini pelacak penjaga. Dalam keadaan di mana palungan proses seharusnya tidak memancarkan sinyal apa pun, Anda memberinya koneksi inert ke dunia. Dengan kata lain, dispatch(command)adalah no-op.


1
Anda berkata: Anda dapat membangun kembali manajer proses dari sejarah acara setiap kali Anda membutuhkannya ... Tetapi untuk membangunnya kembali, saya perlu menyimpan acara untuk itu. Atau haruskah saya membangunnya kembali dari peristiwa dalam agregat? Bagian yang saya perjuangkan adalah: dengan agregat, peristiwa memiliki id agregat, dan mudah untuk membangun kembali dengan menemukan semua peristiwa dengan id agregat itu. Tetapi bagaimana saya melakukannya untuk manajer proses? Haruskah saya melakukan itu untuk manajer proses? Atau haruskah manajer proses mencari agregat ketika perlu memutuskan sesuatu berdasarkan suatu peristiwa yang datang?
Ivan Pintar

Apa yang saya lewatkan adalah gagasan sebab akibat dan korelasi dalam sumber acara. Begitu saya melihat ke dalamnya, maka jawaban Anda untuk pertanyaan keempat akhirnya masuk akal.
Ivan Pintar

1
Saya ingin jawaban atas komentar pertama @IvanPintar; haruskah manajer proses mengambil agregat? Haruskah mereka membangun sendiri berdasarkan pada peristiwa yang diprosesnya? Dalam hal ini event handler harus bebas efek samping, bukan?
Jeff

@ Jeff Di salah satu contoh yang saya lakukan, manajer proses memiliki penyimpanannya sendiri yang diperbarui dengan setiap acara yang diproses, semacam model baca. Ini mudah dilakukan dan mudah untuk melacak apa yang sudah diproses. Dalam contoh lain, manajer proses membuat dan menyimpan acara itu sendiri, dibangun dari peristiwa agregat. Mirip dengan di atas, tetapi negara bersumber dari peristiwa. Bergantung pada kompleksitas keadaan yang disimpan oleh manajer proses, mungkin lebih mudah untuk melakukan satu atau yang lain. Saya menemukan pendekatan pertama lebih sederhana.
Ivan Pintar

Menarik, jadi kurang lebih tergantung pada pengembang selama manajer proses merespons acara dan mengirimkan perintah pada akhirnya?
Jeff

2

Apa yang Anda cari memiliki pola yang disebut "Saga", yang pada dasarnya adalah manajer proses.

Saga juga sempurna untuk proses yang berjalan lama, karena dapat mempertahankan status di antara perintah yang berkorelasi.

Ini adalah artikel bagus tentang Sagas

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.