Compartilhar via


Escalonar um trabalho

Este guia mostra como escalonar um trabalho em uma fila usando uma política de exceção.

Pré-requisitos

Visão geral do escalonamento

O escalonamento pode ter vários comportamentos diferentes, incluindo a mudança de um trabalho para uma fila diferente e/ou a especificação de uma prioridade mais alta. Os trabalhos com prioridade mais alta são distribuídos aos Trabalhadores antes dos trabalhos com prioridade mais baixa. Para este guia de instruções, usamos uma Política de Classificação e uma Política de Exceção para atingir esse objetivo.

Configuração de política de classificação

Crie uma política de classificação para identificar o novo rótulo adicionado ao trabalho. Essa política avalia o rótulo e atribui o Escalated Trabalho a qualquer Fila. A política também usa o Mecanismo de Regras para aumentar a prioridade do Trabalho de 1 para 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)")));

Configuração de política de exceção

Crie uma política de exceção anexada à fila, que é acionada por tempo e executa a ação do Trabalho que está sendo reclassificado.

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"));

Configuração da fila

Crie as Filas necessárias para Trabalhos regulares e escalonados e atribua a Política de Exceção à Fila regular.

Observação

Esta etapa pressupõe que você criou uma política de distribuição já com o nome de 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"));

Ciclo de vida do trabalho

Quando você envia o trabalho, ele é adicionado à fila XBOX_Queue com o voice canal. Para este exemplo específico, o requisito é localizar um trabalhador com um rótulo chamado XBOX_Hardware, que tenha um valor maior ou igual ao número 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)))));

As seguintes etapas do ciclo de vida ocorrem quando a configuração é concluída e o trabalho é enviado:

  1. O trabalho é enviado para o Job Router e produz os RouterJobReceived eventos e RouterJobQueued .
  2. Em seguida, o temporizador de 5 minutos começa e é acionado se nenhum trabalhador correspondente for atribuído. Após 5 minutos, o Job Router emite um RouterJobExceptionTriggered e outro RouterJobQueued evento.
  3. Neste ponto, o trabalho é movido para o XBOX_Escalation_Queue e a prioridade é definida como 10.