Bisakah Anda menulis Deadlock di Camunda BPM? Dan saya bisa

gambar


Beberapa waktu yang lalu saya menulis tentang migrasi sukses dari IBM BPM ke Camunda, dan sekarang hidup kita penuh dengan kebahagiaan dan kesan yang menyenangkan. Camunda tidak mengecewakan, dan kami terus berteman dengan mesin BPM ini.



Tapi, sayangnya, Camunda juga bisa menghadirkan kejutan yang tidak menyenangkan, karena yang kadang-kadang bukan hasil yang paling jelas diperoleh. Artikel ini akan membahas satu kasus, yang, meskipun sederhana, ternyata menarik dan agak lebih rumit daripada yang terlihat pada pandangan pertama.



Kami melatih kucing



Untuk menggambarkan masalah, pertimbangkan contoh sintetis. Katakanlah kami memutuskan untuk memperluas basis klien kami dan perlu melayani kucing dan kucing. Setiap klien potensial harus diperiksa dan, mungkin, segera menawarkan sesuatu.



Kami akan memeriksa keandalan kandidat dan kemungkinan layanan yang dapat kami tawarkan kepadanya. Pemeriksaan keandalan dan layanan yang mungkin tidak terhubung dengan cara apa pun - tindakan ini dapat dilakukan secara paralel. Secara skematis, dalam diagram bpmn, akan terlihat seperti ini:





Diagram 1. Proses skematis dari servis yang halus



Diagram secara skematis menunjukkan langkah-langkah utama, forking dan mengumpulkan (bergabung) gateway.





Ikon ini menggambarkan gateway paralel. Parallel Gateway adalah gateway paling sederhana untuk membangun bagian proses yang berjalan paralel.



Ada dua jenis gateway paralel:



  • fork - membuat eksekusi terpisah untuk setiap cabang;
  • join - tunggu semua eksekusi yang masuk.


Eksekusi - mewakili 'jalur eksekusi' dalam proses contoh (dari dokumentasi). Artinya, ini adalah utas proses eksekusi.



Sekarang mari kita sedikit mempersulit tugas. Kami akan memeriksa dan mencari layanan sebagai berikut: pertama kami memeriksa status klien, kemudian kami melihat layanan apa yang cocok untuknya, dan kami melakukan beberapa pra-pemrosesan. Selain itu, beberapa layanan mungkin cocok untuk klien sekaligus, jadi kami harus dapat menawarkan semuanya kepada klien.



Karena kami bekerja dengan pelanggan berbulu, maka layanan akan sesuai: valerian, anjing cakar, bantal utama dan hal-hal berguna lainnya.





Bagan 2. Bagan Layanan Pelanggan Halus Halus



Versi baru dari prosesnya terlihat seperti ini. Proses ini akan paralel dengan pemeriksaan reliabilitas dan mencari saran yang mungkin. Pencarian juga diparalelkan. Dalam hal ini, cabang-cabang tersebut akan dieksekusi di mana kondisi yang sesuai akan dipenuhi.



Untuk paralelisasi dengan kondisi, Gateway Inklusif digunakan, yang ditandai dengan ikon berikut:





Inclusive Gateway - gateway paralel dengan kondisi cabang. Cabang akan dieksekusi di mana kondisinya benar.



Ada dua jenis gateway:



  • fork - untuk setiap cabang dengan kondisi terpenuhi, eksekusi dibuat, yang dieksekusi secara paralel dengan cara yang sama seperti eksekusi di Parallel Gateway;
  • bergabung, tidak seperti Parallel Gateway, menunggu eksekusi tidak untuk semua cabang, tetapi hanya untuk mereka yang kondisinya benar.


Mungkin saja pemeriksaan yang dilakukan tidak cukup dan klien harus diperiksa lagi. Untuk melakukan ini, tambahkan kondisi di akhir semua pemeriksaan, yang dapat dikirim untuk memeriksa ulang di awal:





Diagram 3. Versi akhir dari proses yang seharusnya berfungsi



Ternyata rumit, tetapi proses menyelesaikan masalah.



Apa? Apa yang terjadi?



Di sini hal-hal aneh mulai terjadi. Cabang pemeriksaan keandalan bekerja dan mencapai gateway paralel pengumpulan. Sejauh ini, semuanya baik-baik saja.



Cabang kedua memeriksa keadaan material, dan tergantung pada hasilnya, tugas yang sesuai dijalankan. Selanjutnya, proses berhenti di gateway mengumpulkan Inclusive Gateway dan tidak bergerak lebih jauh. Jika Anda melihat Coockpit (panel admin Kamunda), maka eksekusi akan tergantung pada pengumpulan Inclusive Gateway dan Parallel Gateway.





Diagram 4. Proses pemeliharaan gantung



. Kita dapat mengatakan bahwa kita mengalami kebuntuan dalam proses di Camunda. Dalam hal ini, tidak secara langsung terkait dengan deadlock dari teori pemrograman paralel dan deadlock.



Mencari jawaban



Karena saya tidak memiliki pemahaman yang cukup tentang apa yang terjadi dan mengapa proses itu berhenti, masalahnya harus diselesaikan secara empiris.



Mungkin Anda memerlukan cabang default untuk Gateway Inklusif, dan tanpa itu, prosesnya tidak dapat berjalan secara normal?



Aneh, tentu saja, tetapi coba tambahkan cabang default. Kehadiran cabang default adalah praktik yang baik, karena jika tidak maka tidak ada satu kondisi pun yang dapat dipenuhi dan kemudian kita akan mendapatkan kesalahan.





Diagram 5. Proses layanan dengan cabang default



Kami memulai dan mendapatkan hasil yang sama - proses tetap tergantung pada Gateway Inklusif.



Berikutnya adalah penghitungan semua jenis parameter, membaca dokumentasi, dan ini berlangsung selama setengah hari. Pada upaya berikutnya, prosesnya secara tak terduga melewati jalan yang naas. Cabang bawah dengan Inclusive Gateway berfungsi dalam situasi ketika selama proses pencarian dan debugging, cabang atas dihapus dengan pemeriksaan keandalan klien. Yaitu, ketika proses mengalami degenerasi hanya ke cabang bawah dengan Gateway Inklusif, proses berakhir.





Diagram 6. Proses degenerasi



Ternyata Parallel Gateway memengaruhi Gateway Inklusif. Ini aneh, tidak logis, dan seharusnya tidak.



Bagaimana ini mungkin? Mungkin perlu membaca ulang teori tentang bagaimana Parallel dan Inclusive Gateway bekerja lagi. Apa yang perlu terjadi untuk join gateway untuk menyatukan semua orang dan prosesnya berjalan? Di Internet, mereka menulis bahwa masing-masing pengumpul Gateway Inklusif (gabung) menunggu nomor yang sama untuk masuk sebagai meninggalkan "garpu". Lalu satu pertanyaan lagi tiba-tiba muncul: bagaimana konter ini bekerja?



Apakah kamu? Bagaimana anda bekerja



Masalah ini layak untuk teka-teki gambar dan acara TV pintar. Hanya di acara TV mereka diizinkan menelepon teman. Di sisi lain, saya juga bisa meminta bantuan. Kami akan memanggil arsitek proses bisnis kami, Denis.



- Denis, halo! Dapatkah Anda memberi tahu saya bagaimana jalur pengumpulan menentukan saat tiba saatnya proses untuk pindah? Di mana-mana mereka menulis: "Berapa banyak yang keluar - begitu banyak yang harus masuk." Tapi bagaimana tepatnya menurutnya?

- Sangat sederhana. Camunda menghitung jumlah eksekusi aktif.

- Terima kasih banyak. Untuk sekarang




Pertimbangkan apa yang terjadi. Untuk melakukan ini, sekali lagi ingat skema awal, yang ternyata:





Diagram 7. Proses gantung dengan cabang default



Untuk mempermudah, mari kita pertimbangkan kasus ketika semua kondisi terpenuhi. Apa yang kita miliki saat tiga tugas setelah kondisi ini terpenuhi?



Berapa banyak eksekusi aktif? Tiga di cabang bawah dan satu di atas, di mana kami memeriksa keandalan klien. Camunda tidak peduli bahwa ini adalah cabang paralel yang berbeda sama sekali. Saya hanya tertarik pada jumlah eksekusi aktif, yang ada empat, dan gateway inklusif yang masuk hanya menerima tiga.



Pemasangan



Untuk memperbaiki situasi, Gateway yang mengumpulkan harus mengumpulkan semua eksekusi sekaligus, dan kemudian, secara teori, proses berjalan. Mari kita coba untuk meninggalkan satu daripada dua bergabung dengan gateway:





Diagram 8. Versi proses yang



diperbaiki Alas, setelah mengedit proses mulai terlihat, menurut pendapat saya, kurang jelas. Tapi itu bekerja sesuai rencana semula. Pada titik ini, pencarian berakhir dengan aman, saya bisa mendorong perubahan dan pulang.



Menarik baru saja dimulai



Ketika saya duduk untuk menulis artikel ini dan menghasilkan sebuah contoh proses di mana saya dapat menggambarkan kasus ini, saya kecewa: prosesnya berjalan sebagaimana mestinya dan tidak ada jalan buntu.



Pada awalnya saya berasumsi bahwa versi Camunda dalam contoh lebih tinggi daripada dalam proyek, dan dalam versi baru masalah ini sudah diperbaiki. Tetapi menurunkan peringkat Camunda tidak melakukan apa-apa. By the way, dalam semua contoh versi 7.8.0 digunakan - itu jauh dari yang terbaru, tetapi itu tidak masalah. Masalah ini juga telah diuji dan direproduksi pada versi terbaru, 7.13.



Melalui trial and error, masalah diperbaiki. Contoh palsu asli tidak memiliki cabang terbalik, tidak seperti proses yang saya kembangkan di tempat kerja.



Ternyata di hadapan cabang terbalik, masalahnya direproduksi dan kita menemukan diri kita dalam semacam jalan buntu, dan tanpa cabang terbalik, semuanya berfungsi sebagaimana mestinya.



Kasus ini menuntut pemahaman dan analisis. Untuk melakukan ini, saya harus melihat kode sumber Bunda Camunda. Karena masalahnya adalah dengan Gateway Inklusif, tampaknya logis untuk mencari jawaban di kelas yang bertanggung jawab atas perilaku elemen ini - InclusiveGatewayActivityBehavior . Menjalankan beberapa kali debug pada kedua versi proses, saya menyadari cara kerjanya.



Jika tidak jelas - lihat sumber!



Agar tidak membuat cerita yang membosankan, deskripsi karya InclusiveGateway berdasarkan kode sumber akan samar. Logika yang menarik bagi kita terkonsentrasi dalam metode eksekusi , di mana metode aktivGateway adalah yang paling berharga untuk kasus ini . Seperti yang saya pahami, ini memeriksa apakah mungkin untuk lulus InclusiveGateway. Metode eksekusi dipanggil untuk setiap eksekusi (untuk setiap cabang yang berjalan). Dalam kasus kami, ada tiga cabang seperti itu, yang berarti bahwa metode ini akan dipanggil tiga kali.



Mari kita lihat bagaimana metode activatesGateway bekerja. Untuk pemahaman yang lebih baik, kami akan memberikan nama untuk semua cabang yang dieksekusi.





Diagram 9. Diagram proses dengan eksekusi



Seperti yang saya pahami, logika dari metode ini adalah sebagai berikut:ada perbandingan jumlah eksekusi yang tiba di jalur ini dan jumlah panah yang termasuk dalam jalur ini . Pemeriksaan ini dilakukan jika ada situasi yang paling sederhana, ketika semua cabang Gateway Inklusif dieksekusi, dan logika memeriksa gerbang pengumpulan adalah menunggu sampai jumlah eksekusi yang dimasukkan sama dengan jumlah panah yang masuk. Artinya, dalam kasus paling sederhana, metode eksekusi dipanggil sebanyak kali karena ada cabang di gateway pengumpulan, kemudian proses berlanjut.



Dalam kasus kami, metode ini disebut tiga kali, karena jumlah eksekusi yang tiba akan meningkat dari 1 menjadi 3. Pada panggilan terakhir, jumlah yang tiba dan yang diharapkan masing-masing adalah 3 dan 4, dan kami akan meninggalkan cabang palsu.



Jika kondisi tidak terpenuhi, eksekusi yang tersisa diperiksa untuk menjadi milik Gateway Inklusif. Yaitu, kemampuan eksekusi aktif untuk masuk ke Gateway inklusif gabungan diperiksa.



Di sini Anda perlu sedikit kesabaran, buang napas, dan baca. Denouement sudah dekat!



Di cabang palsu metode activatesGateway, setiap panggilan yang belum tiba dalam eksekusi gabungan inklusif diperiksa untuk kemungkinan mencapai gabungan ini. Jika setidaknya satu eksekusi dapat mengarah ke Gerbang Inklusif, Anda harus memperhitungkannya dan menunggu untuk datang ke gabung ini juga. Jika tidak ada eksekusi yang dapat menghasilkan join, metode ini akan mengembalikan true.



Bagian yang paling menarik akan datang. Pada pandangan pertama, eksekusi terakhir (eksekusi 1 dalam diagram) tidak dapat mengarah ke Gateway Inklusif. Tetapi perlu melihat penerapan metode canReachActivity , yang terlibat dalam verifikasi ini, dan alasan perilaku elemen ini akan menjadi jelas.



Jika kita membuang semua detail kode, maka di dalam metode ini metode isReachable dipanggil secara berulang, yang, selangkah demi selangkah, memeriksa apakah eksekusi ini dapat masuk ke pengumpulan InclusiveGateway. Cabang terbalik hanya memberikan kesempatan seperti itu, dan, sayangnya, ini diperhitungkan, meskipun seharusnya tidak, karena kami akan kembali setelah semua bergabung.



Akibatnya - Gateway Inklusif sedang menunggu eksekusi lain yang tidak akan pernah datang. Dengan demikian, kita mendapatkan semacam jalan buntu. Pada prinsipnya, jika kita membatalkan konvensi, kita mendapatkan kebuntuan klasik: bergabung dengan Paralel menunggu cabang dengan Inclusive untuk dieksekusi, dan sebaliknya, cabang dengan Inclusive menunggu Paralel untuk dieksekusi.



Diagram di bawah ini menunjukkan arah perkiraan untuk memeriksa ketersediaan sambungan Inclusive Gateway dari eksekusi, yang datang untuk bergabung dengan Prallel Gateway melalui cabang paralel.





Diagram 10. Kemungkinan lintasan dari Parallel Join ke Inclusive Join



Diagram menunjukkan bahwa, memang, join Inclusive Gateway tersedia dari Parallel Gateway join, dan menurut logika Bunda Camunda, tidak masalah bahwa sudah ada β€œlead circle”.



Setelah menemukan alasannya, muncul pertanyaan tanpa sadar: apakah ini bug atau fitur? Menurut pendapat saya, ini adalah bug. Sekarang saya sedang mengumpulkan informasi dan kasing untuk mengirim laporan ke tim Camunda.



Bagus bahwa masalahnya dilokalisasi. Tapi bagaimana dengan sekarang?



Sebenarnya, sekarang - kesimpulannya:



  1. Diperingatkan lebih dulu. Kita perlu membangun proses kita dengan mempertimbangkan perilaku Camunda ini.
  2. , . parallel join.
  3. Inclusive Gateway , , executions .
  4. , . , Parallel Gateway .


Tampak kesederhanaan dan kejelasan terkadang menipu. Ini dapat ditangani hanya melalui akumulasi dan replikasi pengetahuan. Sayangnya, pada saat menyelesaikan masalah ini, saya tidak memiliki pengetahuan yang mendalam tentang logika bergabung dengan Inklusif, jadi saya harus mengotak-atik. Saya memperoleh pengetahuan ini melalui coba, kesalahan, memanggil teman dan sumber debug.



Dari semua ini kesimpulan yang jelas dan jauh dari baru berikut bahwa Anda perlu memahami bagaimana alat yang Anda gunakan bekerja. Semakin baik Anda memahami, semakin sedikit masalah seperti itu.



Kesimpulan kedua juga cukup jelas: Anda perlu mendekomposisikan tidak hanya kode, tetapi juga prosesnya.



Tautan yang bermanfaat dalam menguraikan kasus ini dan menulis artikel:



  1. Sumber Camunda BPM
  2. Deskripsi operasi Gateway Inklusif
  3. Deskripsi Pekerjaan Paralel Gateway



All Articles