Classificando um trabalho
Saiba como usar uma política de classificação no JobRouter para resolver dinamicamente a fila e a prioridade ao anexar seletores de trabalhador a um Trabalho.
Pré-requisitos
- Uma conta do Azure com uma assinatura ativa. Crie uma conta gratuitamente.
- Um recurso dos Serviços de Comunicação implantado. Crie um recurso dos Serviços de Comunicação.
- Opcional: concluir o guia de início rápido de Introdução ao Roteador de Trabalho
Criar uma política de classificação
O exemplo a seguir aproveita o PowerFx Expressions para selecionar a fila e a prioridade. A expressão tenta corresponder ao rótulo Job chamado Region
igual a NA
resultando no Job sendo colocado no XBOX_NA_QUEUE
. Caso contrário, o trabalho será enviado para a fila XBOX_DEFAULT_QUEUE
de fallback, conforme definido pelo fallbackQueueId
. Além disso, a prioridade é 10
se um rótulo chamado Hardware_VIP
foi correspondido, caso contrário, é 1
.
var classificationPolicy = await administrationClient.CreateClassificationPolicyAsync(
new CreateClassificationPolicyOptions(classificationPolicyId: "XBOX_NA_QUEUE_Priority_1_10")
{
Name = "Select XBOX Queue and set priority to 1 or 10",
QueueSelectorAttachments =
{
new ConditionalQueueSelectorAttachment(condition: new ExpressionRouterRule("job.Region = \"NA\""),
queueSelectors: new List<RouterQueueSelector>
{
new(key: "Id", labelOperator: LabelOperator.Equal, value: new RouterValue("XBOX_NA_QUEUE"))
})
},
FallbackQueueId = "XBOX_DEFAULT_QUEUE",
PrioritizationRule = new ExpressionRouterRule("If(job.Hardware_VIP = true, 10, 1)"),
});
var classificationPolicy = await client.path("/routing/classificationPolicies/{classificationPolicyId}",
"XBOX_NA_QUEUE_Priority_1_10").patch({
body: {
name: "Select XBOX Queue and set priority to 1 or 10",
queueSelectorAttachments: [{
kind: "conditional",
condition: {
kind: "expression",
expression: 'job.Region = "NA"'
},
queueSelectors: [{
key: "Id",
labelOperator: "equal",
value: "XBOX_NA_QUEUE"
}]
}],
fallbackQueueId: "XBOX_DEFAULT_QUEUE",
prioritizationRule: {
kind: "expression",
expression: "If(job.Hardware_VIP = true, 10, 1)"
}
},
contentType: "application/merge-patch+json"
});
classification_policy: ClassificationPolicy = administration_client.upsert_classification_policy(
classification_policy_id = "XBOX_NA_QUEUE_Priority_1_10",
name = "Select XBOX Queue and set priority to 1 or 10",
queue_selector_attachments = [
ConditionalQueueSelectorAttachment(
condition = ExpressionRouterRule(expression = 'job.Region = "NA"'),
queue_selectors = [
RouterQueueSelector(key = "Id", label_operator = LabelOperator.EQUAL, value = "XBOX_NA_QUEUE")
]
)
],
fallback_queue_id = "XBOX_DEFAULT_QUEUE",
prioritization_rule = ExpressionRouterRule(expression = "If(job.Hardware_VIP = true, 10, 1)")))
ClassificationPolicy classificationPolicy = administrationClient.createClassificationPolicy(
new CreateClassificationPolicyOptions("XBOX_NA_QUEUE_Priority_1_10")
.setName("Select XBOX Queue and set priority to 1 or 10")
.setQueueSelectors(List.of(new ConditionalQueueSelectorAttachment(
new ExpressionRouterRule("job.Region = \"NA\""),
List.of(new RouterQueueSelector("Id", LabelOperator.EQUAL, new RouterValue("XBOX_NA_QUEUE"))))))
.setFallbackQueueId("XBOX_DEFAULT_QUEUE")
.setPrioritizationRule(new ExpressionRouterRule().setExpression("If(job.Hardware_VIP = true, 10, 1)")));
Enviar o trabalho
O exemplo a seguir faz com que a política de classificação avalie os rótulos de trabalho. O resultado coloca o Trabalho na fila chamada XBOX_NA_QUEUE
e define a prioridade como 1
. Antes que a política de classificação seja avaliada, o estado do trabalho é pendingClassification
. Depois que a política de classificação é avaliada, o estado do trabalho é atualizado para queued
.
var job = await client.CreateJobWithClassificationPolicyAsync(new CreateJobWithClassificationPolicyOptions(
jobId: "job1",
channelId: "voice",
classificationPolicyId: classificationPolicy.Value.Id)
{
Labels =
{
["Region"] = new RouterValue("NA"),
["Caller_Id"] = new RouterValue("7805551212"),
["Caller_NPA_NXX"] = new RouterValue("780555"),
["XBOX_Hardware"] = new RouterValue(7)
}
});
var job = await client.path("/routing/jobs/{jobId}", "job1").patch({
body: {
channelId: "voice",
classificationPolicyId: "XBOX_NA_QUEUE_Priority_1_10",
labels: {
Region: "NA",
Caller_Id: "7805551212",
Caller_NPA_NXX: "780555",
XBOX_Hardware: 7
}
},
contentType: "application/merge-patch+json"
});
job = client.upsert_job(
job_id = "job1",
channel_id = "voice",
classification_policy_id = "XBOX_NA_QUEUE_Priority_1_10",
labels = {
"Region": "NA",
"Caller_Id": "7805551212",
"Caller_NPA_NXX": "780555",
"XBOX_Hardware": 7
}
)
RouterJob job = client.createJob(new CreateJobWithClassificationPolicyOptions("job1", "voice", "XBOX_NA_QUEUE_Priority_1_10")
.setLabels(Map.of(
"Region", new RouterValue("NA"),
"Caller_Id": new RouterValue("7805551212"),
"Caller_NPA_NXX": new RouterValue("780555"),
"XBOX_Hardware": new RouterValue(7)
)));
Anexando seletores de trabalhadores
Você pode usar a política de classificação para anexar mais seletores de trabalho a um trabalho.
Anexos estáticos
Neste exemplo, a Política de Classificação é configurada com um anexo estático, que sempre anexa o seletor de rótulo especificado a um trabalho.
await administrationClient.CreateClassificationPolicyAsync(
new CreateClassificationPolicyOptions("policy-1")
{
WorkerSelectorAttachments =
{
new StaticWorkerSelectorAttachment(new RouterWorkerSelector(
key: "Foo", labelOperator: LabelOperator.Equal, value: new RouterValue("Bar")))
}
});
await client.path("/routing/classificationPolicies/{classificationPolicyId}", "policy-1").patch({
body: {
workerSelectorAttachments: [{
kind: "static",
workerSelector: { key: "Foo", labelOperator: "equal", value: "Bar" }
}]
},
contentType: "application/merge-patch+json"
});
administration_client.upsert_classification_policy(
classification_policy_id = "policy-1",
worker_selector_attachments = [
StaticWorkerSelectorAttachment(
worker_selector = RouterWorkerSelector(key = "Foo", label_operator = LabelOperator.EQUAL, value = "Bar")
)
])
administrationClient.createClassificationPolicy(new CreateClassificationPolicyOptions("policy-1")
.setWorkerSelectorAttachments(List.of(
new StaticWorkerSelectorAttachment(new RouterWorkerSelector("Foo", LabelOperator.EQUAL, new RouterValue("Bar"))))));
Anexos condicionais
Neste exemplo, a Política de Classificação é configurada com um anexo condicional. Assim, ele avalia uma condição em relação aos rótulos de trabalho para determinar se os referidos seletores de rótulos devem ser anexados ao trabalho.
await administrationClient.CreateClassificationPolicyAsync(
new CreateClassificationPolicyOptions("policy-1")
{
WorkerSelectorAttachments =
{
new ConditionalRouterWorkerSelectorAttachment(
condition: new ExpressionRouterRule("job.Urgent = true"),
workerSelectors: new List<RouterWorkerSelector>
{
new(key: "Foo", labelOperator: LabelOperator.Equal, value: new RouterValue("Bar"))
})
}
});
await client.path("/routing/classificationPolicies/{classificationPolicyId}", "policy-1").patch({
body: {
workerSelectorAttachments: [{
kind: "conditional",
condition: { kind: "expression", expression: "job.Urgent = true" },
workerSelectors: [{ key: "Foo", labelOperator: "equal", value: "Bar" }]
}]
},
contentType: "application/merge-patch+json"
});
administration_client.upsert_classification_policy(
classification_policy_id = "policy-1",
worker_selector_attachments = [
ConditionalWorkerSelectorAttachment(
condition = ExpressionRouterRule(expression = "job.Urgent = true"),
worker_selectors = [
RouterWorkerSelector(key = "Foo", label_operator = LabelOperator.EQUAL, value = "Bar")
]
)
])
administrationClient.createClassificationPolicy(new CreateClassificationPolicyOptions("policy-1")
.setWorkerSelectorAttachments(List.of(new ConditionalRouterWorkerSelectorAttachment(
new ExpressionRouterRule("job.Urgent = true"),
List.of(new RouterWorkerSelector("Foo", LabelOperator.EQUAL, new RouterValue("Bar")))))));
Anexos de passagem
Neste exemplo, a Política de Classificação é configurada para anexar um seletor de trabalho ("Foo" = "<value comes from "Foo" label of the job>"
) ao trabalho.
await administrationClient.CreateClassificationPolicyAsync(
new CreateClassificationPolicyOptions("policy-1")
{
WorkerSelectorAttachments =
{
new PassThroughWorkerSelectorAttachment(key: "Foo", labelOperator: LabelOperator.Equal)
}
});
await client.path("/routing/classificationPolicies/{classificationPolicyId}", "policy-1").patch({
body: {
workerSelectorAttachments: [{ kind: "passThrough", key: "Foo", labelOperator: "equal" }]
},
contentType: "application/merge-patch+json"
});
administration_client.upsert_classification_policy(
classification_policy_id = "policy-1",
worker_selector_attachments = [
PassThroughWorkerSelectorAttachment(
key = "Foo", label_operator = LabelOperator.EQUAL, value = "Bar")
])
administrationClient.createClassificationPolicy(new CreateClassificationPolicyOptions("policy-1")
.setWorkerSelectorAttachments(List.of(new PassThroughWorkerSelectorAttachment("Foo", LabelOperator.EQUAL))));
Anexos de alocação ponderada
Neste exemplo, a Política de Classificação é configurada com um anexo de alocação ponderada. Esta política divide os trabalhos de acordo com as ponderações especificadas e atribui diferentes selectores em conformidade. Aqui, 30% dos trabalhos devem ir para trabalhadores com o rótulo Vendor
definido como A
e 70% devem ir para trabalhadores com o rótulo Vendor
definido como B
.
await administrationClient.CreateClassificationPolicyAsync(new CreateClassificationPolicyOptions("policy-1")
{
WorkerSelectorAttachments =
{
new WeightedAllocationWorkerSelectorAttachment(new List<WorkerWeightedAllocation>
{
new (weight: 0.3, workerSelectors: new List<RouterWorkerSelector>
{
new (key: "Vendor", labelOperator: LabelOperator.Equal, value: new RouterValue("A"))
}),
new (weight: 0.7, workerSelectors: new List<RouterWorkerSelector>
{
new (key: "Vendor", labelOperator: LabelOperator.Equal, value: new RouterValue("B"))
})
})
}
});
await client.path("/routing/classificationPolicies/{classificationPolicyId}", "policy-1").patch({
body: {
workerSelectorAttachments: [{
kind: "weightedAllocation",
allocations: [
{
weight: 0.3,
workerSelectors: [{ key: "Vendor", labelOperator: "equal", value: "A" }]
},
{
weight: 0.7,
workerSelectors: [{ key: "Vendor", labelOperator: "equal", value: "B" }]
}]
}]
},
contentType: "application/merge-patch+json"
});
administration_client.upsert_classification_policy(
classification_policy_id = "policy-1",
worker_selector_attachments = [
WeightedAllocationWorkerSelectorAttachment(allocations = [
WorkerWeightedAllocation(weight = 0.3, worker_selectors = [
RouterWorkerSelector(key = "Vendor", label_operator = LabelOperator.EQUAL, value = "A")
]),
WorkerWeightedAllocation(weight = 0.7, worker_selectors = [
RouterWorkerSelector(key = "Vendor", label_operator = LabelOperator.EQUAL, value = "B")
])
])
])
administrationClient.createClassificationPolicy(new CreateClassificationPolicyOptions("policy-1")
.setWorkerSelectorAttachments(List.of(new WeightedAllocationWorkerSelectorAttachment(
List.of(new WorkerWeightedAllocation(0.3, List.of(
new RouterWorkerSelector("Vendor", LabelOperator.EQUAL, new RouterValue("A")),
new RouterWorkerSelector("Vendor", LabelOperator.EQUAL, new RouterValue("B"))
)))))));
Reclassificar um trabalho após o envio
Depois que o JobRouter tiver recebido e classificado um Trabalho usando uma política, você terá a opção de reclassificá-lo usando o SDK. O exemplo a seguir ilustra uma maneira de aumentar a prioridade do Job para 10
, simplesmente especificando o Job ID, chamando o método e atualizando o classificationPolicyId e incluindo o UpdateJobAsync
Hardware_VIP
rótulo.
await client.UpdateJobAsync(new RouterJob("job1") {
ClassificationPolicyId = classificationPolicy.Value.Id,
Labels = { ["Hardware_VIP"] = new RouterValue(true) }});
var job = await client.path("/routing/jobs/{jobId}", "job1").patch({
body: {
classificationPolicyId: classificationPolicy.body.id,
labels: { Hardware_VIP: true }
},
contentType: "application/merge-patch+json"
});
client.upsert_job(
job_id = "job1",
classification_policy_id = classification_policy.id,
labels = { "Hardware_VIP": True }
)
client.updateJob(new RouterJob("job1")
.setClassificationPolicyId(classificationPolicy.getId())
.setLabels(Map.of("Hardware_VIP", new RouterValue(true))));
Observação
Se os rótulos de trabalho, queueId, channelId ou seletores de trabalho forem atualizados, todas as ofertas existentes no trabalho serão revogadas e você receberá um evento RouterWorkerOfferRevoked para cada oferta do EventGrid. O trabalho é enfileirado novamente e você recebe um evento RouterJobQueued . As ofertas de emprego também podem ser revogadas quando a capacidade total de um trabalhador é reduzida ou os canais são atualizados.
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de