
Kuyruk veri yapısı, içerisindeki verilerin/öğelerin FIFO(first in first out) yani ilk gelen ilk çıkar mantığında dizildiği bir listedir. Kuyruğa eklenen veri sıranın en sonuna eklenir. Listeden çekilen ilk veri ise ilk sıradaki olur. Hayal etmekte zorlandıysanız ramazandaki pide kuyruğunu düşünebilirsiniz. Sıraya yeni gelen biri en sona geçer, fırıncı pideyi ilk sırada bekleyene verir ve ilk sıradaki kişi kuyruktan çıkar.

Kuyruk veri yapısının en basit hali yukarıda anlattığım şekildedir. Şimdi olayı biraz daha karmaşıklaştıralım. Kuyruk yapısındaki verilerin her birinin öncelik(priority) değerine sahip olduğu versiyon ise öncelikli kuyruk veri yapısıdır. Bu veri yapısındaki veriler, öncelik derecesine göre farklı sıralara girerler. Hızla hayal edebilmek için yeni bir senaryo oluşturalım. Fırıncı pide satışını iki ayrı kuyruktan oluşturmuş olsun, birinci sırada normal insanlar, ikinci sırada ise beklemek istemeyen ama X TL olan pideye 2X vermek isteyen vakti değerli insanlar olduğunu düşünelim. Bu durumda fırıncı kârını artırmak için sıradaki pideyi, vakti değerli insanlar sırasında ilk sırada bekleyene verecektir. Ta ki vakti değerli insanlar kuyruğunda kimse kalmadığında normal insanlar kuyruğundan pide satmaya devam edecektir.
Kuyruk ve öncelikli kuyruk yapılarının bu örneklerle daha iyi anlaşılacağını düşünüyorum. Artık UiPath ile kuyruk veri yapısının ilişkisinin ne olduğuna geçebiliriz.
RPA projelerini, çalışanların daha önce manuel yürüttüğü dijital iş süreçlerinin otomasyon hale getirilmesi olarak tanımlıyoruz. RPA projelerinde, üzerinde işlem yapılan verilerin belirli bir yerde saklanması ve bu verilerin izlenebilir olması kritik bir görevdir. UiPath buradaki ihtiyacı görmüş olmalı ki kendi Orchestrator sistemine entegre bir Queue(Kuyruk) veri yapısı oluşturmuştur. Bu yazıda UiPath’in kuyruk veri yapısını ve onu nasıl kullanacağımızı inceleyeceğiz.
UiPath Kuyruk Mimarisi
UiPath’in kuyruk veri yapısının Orchestrator sistemine entegre bir sistem olduğundan bahsetmiştim. Dolayısıyla oluşturduğumuz kuyrukların yönetimi ve takibi için de kullanacağımız ortam Orchestrator web arayüzü olacaktır. Orchestrator web arayüzü yardımıyla yeni kuyruklar oluşturabilir, varolan kuyrukların özelliklerini düzenleyebilir ya da kuyruk üzerindeki öğelerin takibini sağlayabiliriz.

UiPath ile RPA projesi geliştirirken kuyruk veri yapısını kullanmak istiyorsanız robotlarınız Orchestrator’a bağlı olmak zorunda. Çünkü kuyruk veri yapısında Orchestrator hem veri ekleme, sıradaki veriyi alma vb fonksiyonları sağlamakta, hem de veriler Orchestrator veritabanındaki tablolarda saklanmaktadır.
UiPath’in kuyruk veri yapısında saklanan her bir öğeyi node(düğüm) olarak isimlendirebiliriz. Kuyruk yapımızdaki node’ların içindeki değerler key-value(anahtar-değer) prensibiyle saklanır. Saklanacak olan veri varsayılan olarak free-form yapıdadır. Yani içerdiği değerler açısından esnektir, Aynı kuyruk içerisinde her node birbirinden farklı sayıda key-value çifti içerebilir. Eğer kendimiz bir kuyruğun veri yapısını sadece belirli bir formatla kısıtlamak istiyorsak bunu da veri yapısını ifade edecek Json Schema’yı belirterek sağlayabiliriz. Eğer sürekli olarak kuyruğa aynı formatta veri eklenecekse Json Schema ile veri yapısını kısıtlamak daha doğru bir seçenek olacaktır.
UiPath Studio’da geliştirdiğimiz bir projeyi kuyruk yapısına uygun yapmak istiyorsak, öğrenmemiz gereken en temel noktalar; sistemdeki object modeli, RPA akışımızda kullanacağımız aktiviteler ve arka planda çalışan mekanizma olacaktır. Sanırım burada ilk olarak QueueItem’dan başlamalıyız. Bu sınıf UiPath’in Core kütüphanesinde bulunan ve kuyruğa atanan ya da kuyruktan okunan verinin saklanacağı nesneyi ifade etmektedir. Yani projelerimizde kuyruk veri yapısına ekleme yaparken ve okuma yaparken bu nesneyi bolca kullanacağız. QueueItem nesnesiyle ilgili bilmemiz gereken bir diğer özellikse bu nesnenin transaction status yani işlem durum değeri içerdiğidir. Bu değerler: New, In Progress, Successful, Failed, Abondoned, Retried ve Deleted şeklindedir. Kuyruk verisinin(QueueItem nesnesi) transaction status değeri, bize o an ne olduğu ve meydana gelen değişimi anlatmakla birlikte, kuyruğun da işlevlerini doğru yürütebilmesi açısından kritik bir öneme sahiptir.
QueueItem sınıfını kısaca tanıdık. Şimdi sırada kullanacağımız aktiviteler var. UiPath Studio’da yer alan kuyruk veri yapısıyla ilişkili aktiviteler her projede default olarak activities paneline eklenmektedir. Bu aktivitelere Activities panelinde Orchestrator klasörü ve onun altında yer alan Queues klasöründen erişebilirsiniz. Aşağıda çok kullanılan kuyruk aktiviteleri ve açıklamalarını bulabilirsiniz.

Add Queue Item: Kuyruğa veri eklemek için kullanılan bir aktivitedir. Bu aktiviteyi kullanırsak, atacağımız öğenin öncelik(priority) değerini kendimiz belirleyebiliz. Kuyruğa eklediğimiz öğe öncelik durumuna göre son sıraya eklenecektir ve transaction status değeri “New” olacaktır. Transaction status değerinin New konumunda olması o öğenin işlenmek üzere sırada beklediğini ifade etmektedir.
Add Transaction Item: Aynı Add Queue Item gibi kuyruğa veri eklemek için kullanılan bir aktivitedir. Ancak bir takım farkları yer almaktadır. Add Transaction Item kullanırsak, atacağımız öğenin öncelik(priority) değerini belirleyemeyiz. Kuyruğa eklediğimiz öğe High Priority yani yüksek öncelikli olarak eklenir. Ayrıca transaction status değeri “New” değil “In Progress” olacaktır. Transaction status değerinin In Progress konumunda olması öğenin o anda işlenmekte olduğunu ifade etmektedir. Dolayısıyla Add Transaction Item aktivitesini kuyruğa eklediğimiz veri üzerinde hemen işlem yapacaksak veya daha sonra işlenmesini istemiyorsak kullanmalıyız.
Get Transaction Item: Kuyruktan veri okumak ve okunan öğeyi hafızaya almak için kullandığımız aktivitedir. Eğer istersek filtreleme işlemi de yapabiliriz. Filtreleme uygulamazsak, sırada en çok bekleyen ve en yüksek öncelikli öğe hafızaya alınacaktır. Eğer kuyrukta bekleyen hiç öğe yoksa o zaman Nothing(Null) değeri atanacaktır.
Set Transaction Status: Biraz yukarıda her QueueItem nesnesinin bir transaction status değeri olduğundan bahsetmiştim. QueueItem nesnelerinin işlem durumu değişimleri çoğunlukla sistemin kendisi(yani Orchestrator) tarafından yapılmaktadır. Ancak sadece bir istisna sözkonusudur. O an işlenmekte olan bir işlemin başarılı mı başarısız mı tamamlandığına sistem karar veremez. Buna sadece bizim yazacağımız algoritma karar verebilir. Dolayısıyla In Progress modundaki bir işlemin Successful veya Failed moduna dönüşümünü sağlamak için kullandığımız bir aktivite vardır. İşte bu aktivite Set Transaction Status aktivitesidir.
Aşağıdaki şemada bir kuyruk öğesinin hangi işlemler sonucu hangi işlem durumlarına geçiş yaptığı gösterilmektedir.

Dispatcher – Performer Yapısı
Bilgisayar bilimlerinde klasik problemlerden bir tanesi üretici-tüketici problemidir. Bu problem; aynı anda üreticinin kuyruğa veri eklediği ve tüketicinin kuyruktan verileri okuyup işlemesi durumunu nasıl optimize edebileceğimiz hakkındadır. Üretici-tüketici problemini çözmek için oluşturulan pek çok yöntem vardır. Dispatcher-Performer yapısı da aslında tam bu problemde olduğu gibi bir optimizasyonu sağlamak için bulunmuş bir yöntemdir. Bazen RPA projesine dönüştürülmesi için operasyon yükü ağır olan işlemler önümüze gelebilir. Bizden bir işlemi aynı anda onlarca robota yaptırmamız talep edilebilir. İşlemi birden fazla aynı anda çalışan robota dağıtmak ve hepsinin birbirinden farklı verilerle çalıştığından emin olmak için düzgün çalışan bir kuyruk yapısına sahip olmamız gerekmektedir. İşte tam bu durumda başvuracağımız en güzel yöntem Dispatcher-Performer yapısı olacaktır.
Dispatcher; veri toplayan ve kuyruğa ileten projeyi, Performer ise; verileri kuyruktan okuyan ve işleyen projedir. Yani bir RPA projesini Dispatcher-Performer mantığıyla gerçekleştirmek için ikiye bölmeli ve iki faz şeklinde geliştirmelisiniz. Bu yöntemi kullanarak robotlarınızı eş zamanlı olarak çalıştırabilirsiniz. Aşağıda çizdiğim şema aslında temel bir Dispatcher-Performer yapısını ifade ediyor. Burada aynı anda 2 robotun Dispatcher projeyi çalıştırarak kuyruğu beslediğini ve 4 farklı robotunsa kuyruktaki verileri okuyarak eşzamanlı olarak birbirinden fazlı öğeler üzerinde işlemler yaptığını görmekteyiz.

Kuyruk veri yapısıyla ilgili temel olarak anlatacaklarım bunlardı. Ama kuyruk veri yapısını incelediğinizde bu yazıda yer almayan bir kaç nüansın daha olduğunu keşfedebilirsiniz. Aşağıda verdiğim kaynakça linkleriyle bilginizi artırabilirsiniz. Eğer bir sorunuz olursa mail adresim (contact@erkanceylan.com) üzerinden veya Linkedin hesabım üzerinden bana iletebilirsiniz.
Esen kalın.
Kaynakça
https://docs.uipath.com/orchestrator/docs/about-queues-and-transactions