Eskalacja zadania
W tym przewodniku pokazano, jak eskalować zadanie w kolejce przy użyciu zasad wyjątków.
Wymagania wstępne
- Konto platformy Azure z aktywną subskrypcją. Utwórz konto bezpłatnie.
- Wdrożony zasób usług komunikacyjnych. Utwórz zasób usług komunikacyjnych.
- Opcjonalnie: ukończ przewodnik Szybki start, aby rozpocząć pracę z routerem zadań
- Opcjonalnie: Zapoznaj się z przewodnikiem z instrukcjami dotyczącymi klasyfikacji zadań
Omówienie eskalacji
Eskalacja może mieć postać kilku różnych zachowań, w tym przeniesienie zadania do innej kolejki i/lub określenie wyższego priorytetu. Zadania o wyższym priorytcie są dystrybuowane do procesów roboczych przed pracą o niższym priorytetu. W tym przewodniku z instrukcjami użyjemy zasad klasyfikacji i zasad wyjątków oraz do osiągnięcia tego celu.
Konfiguracja zasad klasyfikacji
Utwórz zasady klasyfikacji, aby obsłużyć nową etykietę dodaną do zadania. Te zasady oceniają etykietę Escalated
i przypisuje zadanie do jednej z kolejek. Zasady używają również aparatu reguł, aby zwiększyć priorytet zadania z 1
do 10
.
var classificationPolicy = await administrationClient.CreateClassificationPolicyAsync(
new CreateClassificationPolicyOptions(classificationPolicyId: "Classify_XBOX_Voice_Jobs")
{
Name = "Classify XBOX Voice Jobs",
QueueSelectorAttachments =
{
new ConditionalQueueSelectorAttachment(
condition: new ExpressionRouterRule("job.Escalated = true"),
queueSelectors: new List<RouterQueueSelector>
{
new (key: "Id", labelOperator: LabelOperator.Equal, value: new RouterValue("XBOX_Escalation_Queue"))
})
},
PrioritizationRule = new ExpressionRouterRule("If(job.Escalated = true, 10, 1)"),
});
var classificationPolicy = await client.path("/routing/classificationPolicies/{classificationPolicyId}", "Classify_XBOX_Voice_Jobs").patch({
body: {
name: "Classify XBOX Voice Jobs",
queueSelectorAttachments: [{
kind: "conditional",
condition: {
kind: "expression",
expression: 'job.Escalated = true'
},
queueSelectors: [{
key: "Id",
labelOperator: "equal",
value: "XBOX_Escalation_Queue"
}]
}],
prioritizationRule: {
kind: "expression",
expression: "If(job.Escalated = true, 10, 1)"
}
},
contentType: "application/merge-patch+json"
});
classification_policy: ClassificationPolicy = administration_client.upsert_classification_policy(
classification_policy_id = "Classify_XBOX_Voice_Jobs",
name = "Classify XBOX Voice Jobs",
queue_selector_attachments = [
ConditionalQueueSelectorAttachment(
condition = ExpressionRouterRule(expression = 'job.Escalated = true'),
queue_selectors = [
RouterQueueSelector(key = "Id", label_operator = LabelOperator.EQUAL, value = "XBOX_Escalation_Queue")
]
)
],
prioritization_rule = ExpressionRouterRule(expression = "If(job.Escalated = true, 10, 1)")))
ClassificationPolicy classificationPolicy = administrationClient.createClassificationPolicy(
new CreateClassificationPolicyOptions("Classify_XBOX_Voice_Jobs")
.setName("Classify XBOX Voice Jobs")
.setQueueSelectorAttachments(List.of(new ConditionalQueueSelectorAttachment(
new ExpressionRouterRule("job.Escalated = true"),
List.of(new RouterQueueSelector("Id", LabelOperator.EQUAL, new RouterValue("XBOX_Escalation_Queue"))))))
.setPrioritizationRule(new ExpressionRouterRule("If(job.Escalated = true, 10, 1)")));
Konfiguracja zasad wyjątków
Utwórz zasady wyjątków dołączone do kolejki, które są wyzwalane w czasie i podejmuje akcję ponownego sklasyfikowania zadania.
var exceptionPolicy = await administrationClient.CreateExceptionPolicyAsync(new CreateExceptionPolicyOptions(
exceptionPolicyId: "Escalate_XBOX_Policy",
exceptionRules: new List<ExceptionRule>
{
new(
id: "Escalated_Rule",
trigger: new WaitTimeExceptionTrigger(TimeSpan.FromMinutes(5)),
actions: new List<ExceptionAction>
{
new ReclassifyExceptionAction(classificationPolicyId: classificationPolicy.Value.Id)
{
LabelsToUpsert = { ["Escalated"] = new RouterValue(true) }
}
}
)
}) { Name = "Add escalated label and reclassify XBOX Job requests after 5 minutes" });
await client.path("/routing/exceptionPolicies/{exceptionPolicyId}", "Escalate_XBOX_Policy").patch({
body: {
name: "Add escalated label and reclassify XBOX Job requests after 5 minutes",
exceptionRules: [
{
id: "Escalated_Rule",
trigger: { kind: "waitTime", thresholdSeconds: 5 * 60 },
actions: [{ kind: "reclassify", classificationPolicyId: classificationPolicy.body.id, labelsToUpsert: { Escalated: true }}]
}]
},
contentType: "application/merge-patch+json"
});
administration_client.upsert_exception_policy(
exception_policy_id = "Escalate_XBOX_Policy",
name = "Add escalated label and reclassify XBOX Job requests after 5 minutes",
exception_rules = [
ExceptionRule(
id = "Escalated_Rule",
trigger = WaitTimeExceptionTrigger(threshold_seconds = 5 * 60),
actions = [ReclassifyExceptionAction(
classification_policy_id = classification_policy.id,
labels_to_upsert = { "Escalated": True }
)]
)
]
)
administrationClient.createExceptionPolicy(new CreateExceptionPolicyOptions("Escalate_XBOX_Policy",
List.of(new ExceptionAction("Escalated_Rule", new WaitTimeExceptionTrigger(5 * 60),
List.of(new ReclassifyExceptionAction()
.setClassificationPolicyId(classificationPolicy.getId())
.setLabelsToUpsert(Map.of("Escalated", new RouterValue(true))))))
).setName("Add escalated label and reclassify XBOX Job requests after 5 minutes"));
Konfiguracja kolejki
Utwórz niezbędne kolejki dla regularnych i eskalowanych zadań i przypisz zasady wyjątków do regularnej kolejki.
Uwaga
W tym kroku założono, że utworzono już zasady dystrybucji o nazwie Round_Robin_Policy
.
var defaultQueue = await administrationClient.CreateQueueAsync(
new CreateQueueOptions(queueId: "XBOX_Queue", distributionPolicyId: "Round_Robin_Policy")
{
Name = "XBOX Queue",
ExceptionPolicyId = exceptionPolicy.Value.Id
});
var escalationQueue = await administrationClient.CreateQueueAsync(
new CreateQueueOptions(queueId: "XBOX_Escalation_Queue", distributionPolicyId: "Round_Robin_Policy")
{
Name = "XBOX Escalation Queue"
});
await administrationClient.path("/routing/queues/{queueId}", "XBOX_Queue").patch({
body: {
distributionPolicyId: "Round_Robin_Policy",
exceptionPolicyId: exceptionPolicy.body.id,
name: "XBOX Queue"
},
contentType: "application/merge-patch+json"
});
await administrationClient.path("/routing/queues/{queueId}", "XBOX_Escalation_Queue").patch({
body: {
distributionPolicyId: "Round_Robin_Policy",
name: "XBOX Escalation Queue"
},
contentType: "application/merge-patch+json"
});
administration_client.upsert_queue(
queue_id = "XBOX_Queue",
distribution_policy_id = "Round_Robin_Policy",
exception_policy_id = exception_policy.id,
name = "XBOX Queue")
administration_client.upsert_queue(
queue_id = "XBOX_Escalation_Queue",
distribution_policy_id = "Round_Robin_Policy",
name = "XBOX Escalation Queue")
administrationClient.createQueue(new CreateQueueOptions("XBOX_Queue", "Round_Robin_Policy")
.setExceptionPolicyId(exceptionPolicy.getId())
.setName("XBOX Queue"));
administrationClient.createQueue(new CreateQueueOptions("XBOX_Escalation_Queue", "Round_Robin_Policy")
.setName("XBOX Escalation Queue"));
Cykl życia zadania
Po przesłaniu zadania zostanie on dodany do kolejki XBOX_Queue
za pomocą kanału voice
. W tym konkretnym przykładzie wymagane jest znalezienie procesu roboczego z etykietą o nazwie XBOX_Hardware
, która ma wartość większą lub równą liczbie 7
.
await client.CreateJobAsync(new CreateJobOptions(jobId: "job1", channelId: "voice", queueId: defaultQueue.Value.Id)
{
RequestedWorkerSelectors =
{
new RouterWorkerSelector(key: "XBOX_Hardware", labelOperator: LabelOperator.GreaterThanOrEqual, value: new RouterValue(7))
}
});
var job = await client.path("/routing/jobs/{jobId}", "job1").patch({
body: {
channelId: "voice",
queueId: defaultQueue.body.id,
requestedWorkerSelectors: [{ key: "XBOX_Hardware", labelOperator: "GreaterThanOrEqual", value: 7 }]
},
contentType: "application/merge-patch+json"
});
administration_client.upsert_job(
job_id = "job1",
channel_id = "voice",
queue_id = default_queue.id,
requested_worker_selectors = [
RouterWorkerSelector(key = "XBOX_Hardware", label_operator = LabelOperator.GreaterThanOrEqual, value = 7)
])
administrationClient.createJob(new CreateJobOptions("job1", "voice", defaultQueue.getId())
.setRequestedWorkerSelectors(List.of(
new RouterWorkerSelector("XBOX_Hardware", LabelOperator.GREATER_THAN_OR_EQUAL, new RouterValue(7)))));
Następujące kroki cyklu życia są wykonywane po zakończeniu konfiguracji i przesłaniu zadania:
- Zadanie jest wysyłane do routera zadania i generuje
RouterJobReceived
zdarzenia iRouterJobQueued
. - Następnie 5-minutowy czasomierz rozpoczyna się i wyzwala, jeśli nie przypisano pasującego procesu roboczego. Po 5 minutach router zadania emituje i
RouterJobExceptionTriggered
inneRouterJobQueued
zdarzenie. - W tym momencie zadanie przechodzi do
XBOX_Escalation_Queue
elementu , a priorytet jest ustawiony na10
wartość .