İş Kuyruğu
Yürütme Kuyruğunu Yönet
İş yürütme kuyruğunu görüntüleyin ve yönetin, öncelikleri ayarlayın ve iş zamanlamasını kontrol edin.
Kuyruk Durumunu Al
GET /api/{tenantId}/{projectId}/execution/queue
Kuyrukta bekleyen işler, öncelikleri ve tahmini işlem süreleri dahil olmak üzere yürütme kuyruğunun mevcut durumunu getirir.
Parametreler
| Parametre | Tür | Konum | Açıklama |
|---|---|---|---|
tenantId |
GUID | Yol | Kiracı kimliği |
projectId |
GUID | Yol | Proje kimliği |
Sorgu Parametreleri
| Parametre | Tür | Açıklama |
|---|---|---|
priority |
string | Önceliğe göre filtrele: Critical, High, Normal, Low |
jobType |
string | İş türüne göre filtrele: ProcessMining, DataEnrichment, Notebook, Analysis |
includeEstimates |
boolean | Detaylı zaman tahminlerini dahil et (varsayılan: true) |
Yanıt
{
"queueStatus": "Active",
"timestamp": "2024-01-20T10:45:00Z",
"summary": {
"totalQueuedJobs": 23,
"criticalPriorityJobs": 2,
"highPriorityJobs": 7,
"normalPriorityJobs": 12,
"lowPriorityJobs": 2,
"averageWaitTime": "8.5 minutes",
"estimatedProcessingTime": "47 minutes"
},
"processingCapacity": {
"activeWorkers": 4,
"totalWorkers": 6,
"currentLoad": 67,
"maxConcurrentJobs": 8,
"currentlyRunning": 3
},
"queuedJobs": [
{
"jobId": "ff0e8400-e29b-41d4-a716-446655440000",
"jobName": "Customer Analytics Pipeline",
"jobType": "ProcessMining",
"priority": "Critical",
"queuePosition": 1,
"estimatedStartTime": "2024-01-20T10:47:00Z",
"estimatedDuration": "12-15 minutes",
"submittedBy": "user456",
"dateSubmitted": "2024-01-20T10:44:00Z",
"resourceRequirements": {
"cpuUnits": 2,
"memoryGB": 4,
"estimatedDiskUsage": "1.2 GB"
}
},
{
"jobId": "00fe8400-e29b-41d4-a716-446655440000",
"jobName": "Daily Sales Analysis",
"jobType": "DataEnrichment",
"priority": "High",
"queuePosition": 2,
"estimatedStartTime": "2024-01-20T11:02:00Z",
"estimatedDuration": "8-10 minutes",
"submittedBy": "system",
"dateSubmitted": "2024-01-20T10:30:00Z",
"resourceRequirements": {
"cpuUnits": 1,
"memoryGB": 2,
"estimatedDiskUsage": "500 MB"
}
}
],
"performanceMetrics": {
"averageJobDuration": "16.3 minutes",
"throughputLastHour": 12,
"queueTrends": {
"currentHourSubmissions": 8,
"peakHourToday": "09:00-10:00",
"averageQueueSize": 15.7
}
}
}
Önceliğe Göre İşleri Al
GET /api/{tenantId}/{projectId}/execution/queue/priority/{priority}
Özel öncelik seviyesine göre filtrelenmiş kuyruktaki işleri, detaylı pozisyon ve zaman bilgisiyle birlikte getirir.
Parametreler
| Parametre | Tür | Konum | Açıklama |
|---|---|---|---|
priority |
string | Yol | Öncelik seviyesi: Critical, High, Normal, Low |
Yanıt
{
"priority": "High",
"jobCount": 7,
"averageWaitTime": "6.2 minutes",
"estimatedProcessingTime": "31 minutes",
"jobs": [
{
"jobId": "00fe8400-e29b-41d4-a716-446655440000",
"jobName": "Daily Sales Analysis",
"jobType": "DataEnrichment",
"queuePosition": 2,
"overallQueuePosition": 3,
"estimatedStartTime": "2024-01-20T11:02:00Z",
"estimatedCompletion": "2024-01-20T11:12:00Z",
"submittedBy": "system",
"dateSubmitted": "2024-01-20T10:30:00Z",
"waitTime": "15 minutes",
"dependencies": [],
"resourceRequirements": {
"cpuUnits": 1,
"memoryGB": 2,
"estimatedDiskUsage": "500 MB"
}
}
]
}
İş Önceliğini Değiştir
PUT /api/{tenantId}/{projectId}/execution/queue/job/{jobId}/priority
Kuyruktaki bir işin önceliğini günceller, bu da kuyruğundaki pozisyonunu ve tahmini başlama zamanını değiştirebilir.
İstek Gövdesi
{
"newPriority": "Critical",
"reason": "Business critical analysis required urgently",
"notifyUser": true
}
Yanıt
{
"jobId": "00fe8400-e29b-41d4-a716-446655440000",
"previousPriority": "High",
"newPriority": "Critical",
"previousQueuePosition": 3,
"newQueuePosition": 1,
"previousEstimatedStart": "2024-01-20T11:02:00Z",
"newEstimatedStart": "2024-01-20T10:47:00Z",
"timeSaved": "15 minutes",
"updatedBy": "user123",
"updateTime": "2024-01-20T10:46:00Z"
}
İş Pozisyonunu Taşı
PUT /api/{tenantId}/{projectId}/execution/queue/job/{jobId}/position
Bir işin pozisyonunu öncelik seviyesi içinde manuel olarak ayarlar. Pozisyon değişiklikleri yalnızca aynı öncelik düzeyinde yapılabilir.
İstek Gövdesi
{
"newPosition": 1,
"reason": "Dependencies resolved, can execute earlier",
"respectPriorityBoundaries": true
}
Yanıt
{
"jobId": "00fe8400-e29b-41d4-a716-446655440000",
"priority": "High",
"previousPosition": 3,
"newPosition": 1,
"previousEstimatedStart": "2024-01-20T11:02:00Z",
"newEstimatedStart": "2024-01-20T10:55:00Z",
"affectedJobs": [
{
"jobId": "11fe8400-e29b-41d4-a716-446655440000",
"newPosition": 2,
"newEstimatedStart": "2024-01-20T11:05:00Z"
}
],
"updateTime": "2024-01-20T10:46:00Z"
}
Kuyruk İşlemesini Kontrol Et
POST /api/{tenantId}/{projectId}/execution/queue/control
Bakım veya acil durumlar için kuyruk işlemesini duraklatır veya devam ettirir. Çalışmakta olan işler devam eder, ancak duraklatıldığında yeni işler başlamaz.
İstek Gövdesi
{
"action": "pause",
"reason": "System maintenance window",
"duration": 30,
"allowRunningJobsToComplete": true,
"notifyUsers": true,
"scheduledResume": "2024-01-20T12:00:00Z"
}
Yanıt
{
"action": "pause",
"status": "Paused",
"pausedAt": "2024-01-20T10:47:00Z",
"scheduledResume": "2024-01-20T12:00:00Z",
"affectedJobs": 23,
"runningJobsCount": 3,
"estimatedDelayMinutes": 30,
"reason": "System maintenance window",
"pausedBy": "admin123"
}
Kuyruk Geçmişini Al
GET /api/{tenantId}/{projectId}/execution/queue/history
Analiz ve optimizasyon amacıyla geçmiş kuyruk performans verilerini ve metriklerini getirir.
Sorgu Parametreleri
| Parametre | Tür | Açıklama |
|---|---|---|
dateFrom |
datetime | Geçmiş veriler için başlangıç tarihi |
dateTo |
datetime | Geçmiş veriler için bitiş tarihi |
aggregation |
string | Veri toplama seviyesi: hour, day, week (varsayılan: hour) |
metrics |
string | Virgülle ayrılmış metrikler: queue_size, wait_time, throughput, efficiency |
Yanıt
{
"period": {
"startDate": "2024-01-19T00:00:00Z",
"endDate": "2024-01-20T10:47:00Z",
"aggregation": "hour"
},
"summary": {
"totalJobsProcessed": 847,
"averageQueueSize": 12.3,
"averageWaitTime": "7.8 minutes",
"peakQueueSize": 45,
"peakWaitTime": "23 minutes",
"throughputPerHour": 24.8,
"efficiency": 87.2
},
"hourlyData": [
{
"timestamp": "2024-01-20T09:00:00Z",
"queueSize": {
"average": 18,
"peak": 25,
"minimum": 8
},
"waitTime": {
"average": "9.5 minutes",
"maximum": "18 minutes",
"minimum": "2 minutes"
},
"throughput": {
"jobsCompleted": 28,
"jobsSubmitted": 31,
"efficiency": 89.3
},
"priorityDistribution": {
"critical": 2,
"high": 8,
"normal": 14,
"low": 1
}
}
],
"trends": {
"queueSizeGrowth": -2.3,
"waitTimeImprovement": 5.7,
"throughputIncrease": 12.1,
"efficiencyChange": 3.4
},
"bottlenecks": [
{
"timeframe": "2024-01-20T08:30:00Z - 2024-01-20T09:15:00Z",
"issue": "High memory usage jobs accumulated",
"impact": "15 minute delay",
"resolution": "Additional worker allocated"
}
]
}
Kullanıcının Kuyruktaki İşlerini İptal Et
DELETE /api/{tenantId}/{projectId}/execution/queue/user/{userId}
Belirli bir kullanıcının kuyrukta bekleyen tüm işlerini iptal eder. Kullanıcının çalışmakta olan işleri tamamlanmaya devam eder.
İstek Gövdesi (İsteğe Bağlı)
{
"reason": "User account deactivated",
"notifyUser": false,
"cancelJobTypes": ["ProcessMining", "DataEnrichment"],
"excludeJobIds": ["important-job-id-1", "important-job-id-2"]
}
Yanıt
{
"userId": "user123",
"cancelledJobsCount": 5,
"preservedJobsCount": 2,
"cancelledJobs": [
{
"jobId": "job1-guid",
"jobName": "Weekly Analysis",
"priority": "Normal",
"queuePosition": 8
}
],
"preservedJobs": [
{
"jobId": "important-job-id-1",
"jobName": "Critical Business Report",
"reason": "Explicitly excluded"
}
],
"cancelledAt": "2024-01-20T10:47:00Z",
"cancelledBy": "admin123"
}
Kuyruk Tahminlerini Al
GET /api/{tenantId}/{projectId}/execution/queue/predictions
Kuyruk davranışı, optimal gönderim zamanları ve kaynak tahsisi önerileri için yapay zeka destekli tahminler sağlar.
Sorgu Parametreleri
| Parametre | Tür | Açıklama |
|---|---|---|
horizon |
integer | Tahmin süresi saat olarak (1-24, varsayılan: 4) |
jobType |
string | Belirli iş türü için tahmin yap |
includeRecommendations |
boolean | Optimizasyon önerilerini dahil et (varsayılan: true) |
Yanıt
{
"predictionTime": "2024-01-20T10:47:00Z",
"horizon": 4,
"predictions": {
"queueSizeProjection": [
{
"time": "2024-01-20T11:00:00Z",
"expectedQueueSize": 18,
"confidence": 0.87
},
{
"time": "2024-01-20T12:00:00Z",
"expectedQueueSize": 12,
"confidence": 0.82
}
],
"waitTimeProjection": [
{
"time": "2024-01-20T11:00:00Z",
"averageWaitTime": "6.5 minutes",
"confidence": 0.85
}
],
"resourceUtilization": [
{
"time": "2024-01-20T11:00:00Z",
"cpuUtilization": 78,
"memoryUtilization": 65,
"efficiency": 89.2
}
]
},
"recommendations": {
"optimalSubmissionTimes": [
{
"timeWindow": "2024-01-20T13:00:00Z - 2024-01-20T15:00:00Z",
"expectedWaitTime": "3-5 minutes",
"reason": "Low queue activity period"
}
],
"resourceOptimization": [
{
"recommendation": "Add 1 additional worker node",
"expectedImprovement": "25% reduction in wait times",
"cost": "Low",
"priority": "Medium"
}
],
"jobScheduling": [
{
"jobType": "ProcessMining",
"recommendation": "Schedule during off-peak hours (14:00-16:00)",
"reason": "Memory-intensive jobs perform better with less contention"
}
]
},
"modelInfo": {
"modelVersion": "2.1.3",
"lastTrained": "2024-01-19T02:00:00Z",
"accuracy": 0.84,
"dataPoints": 10080
}
}
Örnek: Kuyruk Yönetimi İş Akışı
Bu örnek, iş kuyruğunu izleme ve yönetmeyi gösterir:
// 1. Geçerli kuyruk durumunu al
const getQueueStatus = async () => {
const response = await fetch('/api/{tenantId}/{projectId}/execution/queue?includeEstimates=true', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const queue = await response.json();
console.log(`Kuyruk Durumu: ${queue.queueStatus}`);
console.log(`Toplam iş: ${queue.summary.totalQueuedJobs}`);
console.log(`Ortalama bekleme süresi: ${queue.summary.averageWaitTime}`);
return queue;
};
// 2. Gerekirse iş önceliğini değiştir
const updateJobPriority = async (jobId, newPriority, reason) => {
const response = await fetch(`/api/{tenantId}/{projectId}/execution/queue/job/${jobId}/priority`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
newPriority: newPriority,
reason: reason,
notifyUser: true
})
});
const result = await response.json();
console.log(`İş ${jobId} önceliği ${result.previousPriority} iken ${result.newPriority} olarak değiştirildi`);
console.log(`Yeni pozisyon: ${result.newQueuePosition} (öncekinden: ${result.previousQueuePosition})`);
console.log(`Kazandırılan zaman: ${result.timeSaved}`);
return result;
};
// 3. Optimizasyon için kuyruk tahminlerini al
const getQueuePredictions = async () => {
const response = await fetch('/api/{tenantId}/{projectId}/execution/queue/predictions?horizon=4&includeRecommendations=true', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const predictions = await response.json();
console.log('Kuyruk Tahminleri:');
predictions.predictions.queueSizeProjection.forEach(prediction => {
console.log(` ${prediction.time}: ${prediction.expectedQueueSize} iş (${Math.round(prediction.confidence * 100)}% güven)`);
});
console.log('Öneriler:');
predictions.recommendations.optimalSubmissionTimes.forEach(rec => {
console.log(` Gönderim zamanı: ${rec.timeWindow} (${rec.expectedWaitTime} bekleme)`);
});
return predictions;
};
// 4. Belirli bir işi kuyrukta izle
const monitorJobInQueue = async (jobId) => {
const checkQueue = async () => {
const queue = await getQueueStatus();
const job = queue.queuedJobs.find(j => j.jobId === jobId);
if (job) {
console.log(`İş ${jobId} şu pozisyonda: ${job.queuePosition}`);
console.log(`Tahmini başlama: ${job.estimatedStartTime}`);
console.log(`Tahmini süre: ${job.estimatedDuration}`);
// 2 dakika sonra tekrar kontrol et
setTimeout(() => checkQueue(), 120000);
} else {
console.log(`İş ${jobId} artık kuyrukta değil (muhtemelen başladı veya iptal edildi)`);
}
};
await checkQueue();
};
// 5. Acil kuyruk yönetimi
const pauseQueue = async (reason, duration) => {
const response = await fetch('/api/{tenantId}/{projectId}/execution/queue/control', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
action: 'pause',
reason: reason,
duration: duration,
allowRunningJobsToComplete: true,
notifyUsers: true
})
});
const result = await response.json();
console.log(`Kuyruk duraklatıldı: ${result.status}`);
console.log(`${result.affectedJobs} iş etkilendi`);
console.log(`Tahmini gecikme: ${result.estimatedDelayMinutes} dakika`);
return result;
};
// Kuyruk yönetim iş akışını çalıştır
getQueueStatus()
.then(queue => {
console.log('Mevcut kuyruk durumu alındı');
// Kuyruk çok uzadı mı kontrol et
if (queue.summary.totalQueuedJobs > 30) {
console.log('Kuyruk uzun, tahminler kontrol ediliyor...');
return getQueuePredictions();
}
return null;
})
.then(predictions => {
if (predictions) {
console.log('Kuyruk tahminleri alındı');
// Tahminler büyüme gösteriyorsa kaynak optimizasyonunu değerlendir
const futureQueueSize = predictions.predictions.queueSizeProjection[predictions.predictions.queueSizeProjection.length - 1];
if (futureQueueSize.expectedQueueSize > 25) {
console.log('Kaynak optimizasyonu önerilerini uygulamayı düşünün');
predictions.recommendations.resourceOptimization.forEach(rec => {
console.log(`- ${rec.recommendation}: ${rec.expectedImprovement}`);
});
}
}
})
.catch(error => console.error('Kuyruk yönetimi başarısız oldu:', error));
Python Örneği
import requests
import time
import json
from datetime import datetime, timedelta
class QueueManager:
def __init__(self, base_url, tenant_id, project_id, token):
self.base_url = base_url
self.tenant_id = tenant_id
self.project_id = project_id
self.headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
def get_queue_status(self, priority=None, job_type=None, include_estimates=True):
"""Geçerli kuyruk durumunu al"""
url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/execution/queue"
params = {'includeEstimates': str(include_estimates).lower()}
if priority:
params['priority'] = priority
if job_type:
params['jobType'] = job_type
response = requests.get(url, params=params, headers=self.headers)
return response.json()
def get_jobs_by_priority(self, priority):
"""Öncelik seviyesine göre filtrelenmiş işleri al"""
url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/execution/queue/priority/{priority}"
response = requests.get(url, headers=self.headers)
return response.json()
def change_job_priority(self, job_id, new_priority, reason, notify_user=True):
"""Kuyruktaki bir işin önceliğini değiştir"""
url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/execution/queue/job/{job_id}/priority"
payload = {
'newPriority': new_priority,
'reason': reason,
'notifyUser': notify_user
}
response = requests.put(url, json=payload, headers=self.headers)
return response.json()
def move_job_position(self, job_id, new_position, reason):
"""İşi öncelik seviyesinde yeni pozisyona taşı"""
url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/execution/queue/job/{job_id}/position"
payload = {
'newPosition': new_position,
'reason': reason,
'respectPriorityBoundaries': True
}
response = requests.put(url, json=payload, headers=self.headers)
return response.json()
def control_queue(self, action, reason, duration=None, scheduled_resume=None):
"""Kuyruk işlemesini duraklat veya devam ettir"""
url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/execution/queue/control"
payload = {
'action': action,
'reason': reason,
'allowRunningJobsToComplete': True,
'notifyUsers': True
}
if duration:
payload['duration'] = duration
if scheduled_resume:
payload['scheduledResume'] = scheduled_resume.isoformat()
response = requests.post(url, json=payload, headers=self.headers)
return response.json()
def get_queue_history(self, date_from, date_to, aggregation='hour', metrics=None):
"""Geçmiş kuyruk performans verilerini al"""
url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/execution/queue/history"
params = {
'dateFrom': date_from.isoformat(),
'dateTo': date_to.isoformat(),
'aggregation': aggregation
}
if metrics:
params['metrics'] = ','.join(metrics)
response = requests.get(url, params=params, headers=self.headers)
return response.json()
def cancel_user_jobs(self, user_id, reason, job_types=None, exclude_job_ids=None):
"""Belirli bir kullanıcının tüm kuyruktaki işlerini iptal et"""
url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/execution/queue/user/{user_id}"
payload = {
'reason': reason,
'notifyUser': False
}
if job_types:
payload['cancelJobTypes'] = job_types
if exclude_job_ids:
payload['excludeJobIds'] = exclude_job_ids
response = requests.delete(url, json=payload, headers=self.headers)
return response.json()
def get_queue_predictions(self, horizon=4, job_type=None, include_recommendations=True):
"""Yapay zeka destekli kuyruk tahminlerini al"""
url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/execution/queue/predictions"
params = {
'horizon': horizon,
'includeRecommendations': str(include_recommendations).lower()
}
if job_type:
params['jobType'] = job_type
response = requests.get(url, params=params, headers=self.headers)
return response.json()
def monitor_queue_health(self, alert_threshold=30, check_interval=300):
"""Kuyruk sağlığını sürekli izle ve sorunlarda uyar"""
while True:
try:
queue_status = self.get_queue_status()
total_jobs = queue_status['summary']['totalQueuedJobs']
avg_wait = queue_status['summary']['averageWaitTime']
print(f"Kuyruk Sağlık Kontrolü: {total_jobs} iş, ortalama bekleme: {avg_wait}")
if total_jobs > alert_threshold:
print(f"UYARI: Kuyruk büyüklüğü ({total_jobs}) eşik ({alert_threshold}) değerini aştı")
# Gelişmeleri görmek için tahminleri al
predictions = self.get_queue_predictions()
future_size = predictions['predictions']['queueSizeProjection'][-1]['expectedQueueSize']
if future_size > total_jobs:
print("UYARI: Kuyruğun daha da büyümesi bekleniyor")
print("Kaynak optimizasyonu önerileri:")
for rec in predictions['recommendations']['resourceOptimization']:
print(f" - {rec['recommendation']}: {rec['expectedImprovement']}")
time.sleep(check_interval)
except Exception as e:
print(f"Kuyruk izleme hatası: {e}")
time.sleep(60)
# Kullanım örneği
manager = QueueManager(
'https://your-mindzie-instance.com',
'tenant-guid',
'project-guid',
'your-auth-token'
)
try:
# Kapsamlı kuyruk durumu al
queue_status = manager.get_queue_status(include_estimates=True)
print(f"Kuyruk Durumu: {queue_status['queueStatus']}")
print(f"Kuyruktaki toplam işler: {queue_status['summary']['totalQueuedJobs']}")
print(f"Ortalama bekleme süresi: {queue_status['summary']['averageWaitTime']}")
print(f"İşlem kapasitesi: %{queue_status['processingCapacity']['currentLoad']}")
# Özellikle yüksek öncelikli işleri kontrol et
high_priority_jobs = manager.get_jobs_by_priority('High')
print(f"Yüksek öncelikli işler: {high_priority_jobs['jobCount']}")
# Önümüzdeki 4 saat için kuyruk tahminleri al
predictions = manager.get_queue_predictions(horizon=4)
print("Kuyruk tahminleri:")
for pred in predictions['predictions']['queueSizeProjection']:
confidence_pct = round(pred['confidence'] * 100)
print(f" {pred['time']}: {pred['expectedQueueSize']} iş (%{confidence_pct} güven)")
# Önerileri kontrol et
if predictions['recommendations']['optimalSubmissionTimes']:
print("Optimal gönderim zamanları:")
for rec in predictions['recommendations']['optimalSubmissionTimes']:
print(f" {rec['timeWindow']}: {rec['expectedWaitTime']} bekleme süresi")
# Örnek: Gerekirse bir işin önceliğini yükselt
if queue_status['summary']['totalQueuedJobs'] > 20:
# Normal öncelikli bir işi bul
normal_jobs = [job for job in queue_status['queuedJobs'] if job['priority'] == 'Normal']
if normal_jobs:
job_to_elevate = normal_jobs[0]
result = manager.change_job_priority(
job_to_elevate['jobId'],
'High',
'Kuyruk yoğunluğu - iş kritik olarak yükseltiliyor'
)
print(f"{job_to_elevate['jobName']} işi yüksek önceliğe yükseltildi")
print(f"Yeni pozisyon: {result['newQueuePosition']} (öncekinden: {result['previousPosition']})")
# Analiz için kuyruk geçmişini al
history = manager.get_queue_history(
datetime.now() - timedelta(hours=24),
datetime.now(),
'hour',
['queue_size', 'wait_time', 'throughput']
)
print(f"24 saat özeti: {history['summary']['totalJobsProcessed']} iş işlendi")
print(f"Zirve kuyruk büyüklüğü: {history['summary']['peakQueueSize']}")
print(f"Ortalama iş hacmi: {history['summary']['throughputPerHour']} iş/saat")
# Dar boğaz varsa raporla
if history['bottlenecks']:
print("Son dar boğazlar:")
for bottleneck in history['bottlenecks']:
print(f" {bottleneck['timeframe']}: {bottleneck['issue']} (Etkisi: {bottleneck['impact']})")
except Exception as e:
print(f"Kuyruk yönetiminde hata: {e}")