Tamamen can sıkıntısından oluşturduğum bu prensibi sizlerle de paylaşmak istedim. Üzerinde araştırma yapıp veya şunu şöyle yapsak daha iyi olur diye geliştirdiğim bir şey değil, o yüzden kesinlikle daha iyi bir method vardır. Bu benim hayal gücümün ürünü diyelim.
Öncelikle bize döngüler içinde döngüler içeren, karışık bir kod lazım ki bu fonksiyonun çalışıp çalışmadığını kontrol edelim. Eskiden sürekli terminali spamlardım. Bunu da o yüzden yazdım, akan yazılar görecek havamda değildim ve hata ayıklayıcı kullanıyordum zaten. Ben de bittiğinde terminal çöplük olmasın, ama ne oluyor takip edilsin diye yaptım.
Benim spagettiyi sizinle paylaşamayacağım için size örnek olarak sadece rastgele süre bekleyen bir fonksiyon verebilirim.
Python:
import random
import time
import shutil # ileride kullanılacak
def worker_progress():
while 1:
worker_job = [
"Dosyalar taranıyor",
"Akşama yemek pişiriliyor",
"Çocuklara bakılıyor",
"API hizmetleri sorgulanıyor",
"Çalışıyormuş gibi yapılıyor",
"Disk temizliği yapılıyor",
"Virüsler ağırlanıyor",
"Oylar sayılıyor",
"Matematik hesaplamaları sürüyor"
]
current_job = random.choice(worker_job)
circle_count = random.randint(5,20)
circle_wait_time = random.randint(10,50)/100
circled = 0
while (circled < circle_count):
circle("current_job")
time.sleep(circle_wait_time)
if (random.randint(1,5) == 3): # işin cilvesi
time.sleep(10)
Bu bizim bazen çalışan, bazen işlemleri uzun süren, bazen de ne yaptığını kendisi de bilmeyen spagetti kodumuz. Bir spagetti yazarken boş bulduğumuz yere circle fonksiyonunu eklemeliyiz. Bu circle fonksiyonu, bizim kod yürütmesinde bir yerlere geldiğimizi bildirir. Çağırılmadığında yanıt vermiyor olarak öngöreceğiz. Yukarıda da minik bir ihtimal kod yürütmesini tıkayacak bir fonksiyon mevcut.
Bizim yapacağımız şey çoklu işlem modülüyle bir izleyici bir de spagetti fonksiyon çalıştırmak. İzleyici içerisinde bir fonksiyonumuz spagetti kodun derdini anlatması için, diğer fonksiyonumuz da terminalin iletişim kurması için kullanılacak.
Her şeyden önce değişkenlerimizi önden tanımlayalım.
Python:
circlestage = 0
circleepoch = time.time()
circlereason = "Başlıyor"
Spagettinin derdini anlatması için fonksiyonumuzu yazalım. Bu fonksiyonu, spagettide müsait gördüğünüz yerlere yerleştirebilirsiniz. Kilitlenmeyi sebep olarak bildirerek yanıt vermiyor bildirimini açıklayabilirsiniz. Örneğin, bir dosya indirmeden hemen önce bilgili bir şekilde yerleştirmek IO'nun kilitlendiğini de bildirmek için iyi bir yoldur. Çıktısı
| Yanıt vermiyor | Dosya indiriliyor
olursa spagettiyi boş yere sıkıştırmamış oluruz.
Python:
def circle(reason):
global circleepoch
global circlestage
global circlereason
circlereason = reason
if circlestage == 4:
circlestage = 0
circlestage += 1
circleepoch = time.time()
Bu fonksiyon ile güncel tuttuğumuz çalışma durumunu bir de ekrana yazdıracak bir fonksiyon lazım. Onu da başka bir fonksiyon olarak çalıştıracağız.
Python:
def circle_terminal():
global circlestage
global circleepoch
global circlereason
circlereason_local = circlereason
is_stuck = False
if time.time() - circleepoch > 0.5:
is_stuck = True
if is_stuck:
circlereason_local = "Yanıt vermiyor ("+str(int(time.time() - circleepoch))+"sn) | "+circlereason
progress = [
"|",
"/",
"-",
"\\",
]
text = " "+progress[circlestage]+" "+circlereason_local
window_size = shutil.get_terminal_size()
full_window_text = text+" "*(window_size[0]-len(text))
print(full_window_text, end="\r")
Yazmaktan da yoruldum şimdi. Taşları birleştirip gidiyorum. Threads modülünü alıp yapıştıracaksınız
Python:
import random
import time
import shutil
import threading
circlestage = 0
circleepoch = time.time()
circlereason = "Başlıyor"
lock = threading.Lock()
def worker_progress():
while True:
worker_job = [
"Dosyalar taranıyor",
"Akşama yemek pişiriliyor",
"Çocuklara bakılıyor",
"API hizmetleri sorgulanıyor",
"Çalışıyormuş gibi yapılıyor",
"Disk temizliği yapılıyor",
"Virüsler ağırlanıyor",
"Oylar sayılıyor",
"Matematik hesaplamaları sürüyor"
]
current_job = random.choice(worker_job)
circle_count = random.randint(5, 20)
circle_wait_time = random.randint(10, 50) / 100
circled = 0
while circled < circle_count:
circle(current_job)
time.sleep(circle_wait_time)
if random.randint(1, 10) == 7:
time.sleep(10)
circled += 1
def circle(reason):
global circleepoch
global circlestage
global circlereason
with lock:
circlereason = reason
circlestage += 1
circleepoch = time.time()
def circle_terminal():
global circlestage
global circleepoch
global circlereason
circlereason_local = circlereason
is_stuck = False
if time.time() - circleepoch > 0.5:
is_stuck = True
if is_stuck:
circlereason_local = "Yanıt vermiyor (" + str(int(time.time() - circleepoch)) + "sn) | " + circlereason
progress = ["|", "/", "-", "\\"]
if circlestage >= 4:
circlestage = 0
text = " " + progress[circlestage] + " " + circlereason_local
window_size = shutil.get_terminal_size()
full_window_text = text + " " * (window_size[0] - len(text))
print(full_window_text, end="\r")
def main():
while True:
circle_terminal()
time.sleep(0.2)
threading.Thread(target=worker_progress).start()
threading.Thread(target=main).start()