Classificazione di un processo
Informazioni su come usare un criterio di classificazione in Job Router per risolvere dinamicamente la coda e la priorità, collegando al tempo stesso i selettori di lavoro a un processo.
Prerequisiti
- Un account Azure con una sottoscrizione attiva. Creare un account gratuitamente.
- Una risorsa di Servizi di comunicazione distribuita. Creare una risorsa di Servizi di comunicazione.
- Facoltativo: Completare la guida introduttiva per iniziare a usare Il router di processo
Creare criteri di classificazione
Nell'esempio seguente vengono usate espressioni PowerFx per selezionare sia la coda che la priorità. L'espressione tenta di trovare la corrispondenza con l'etichetta processo denominata Region
uguale a NA
, con conseguente inserimento del processo nell'oggetto XBOX_NA_QUEUE
. In caso contrario, il processo viene inviato alla coda XBOX_DEFAULT_QUEUE
di fallback come definito da fallbackQueueId
. Inoltre, la priorità è 10
se è stata trovata una corrispondenza con un'etichetta chiamata Hardware_VIP
, in caso contrario è 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)")));
Inviare il processo
Nell'esempio seguente i criteri di classificazione valutano le etichette processo. Il risultato inserisce il processo nella coda chiamata XBOX_NA_QUEUE
e imposta la priorità su 1
. Prima di valutare i criteri di classificazione, lo stato del processo è pendingClassification
. Dopo aver valutato i criteri di classificazione, lo stato del processo viene aggiornato a 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)
)));
Collegamento di selettori di lavoro
È possibile usare i criteri di classificazione per collegare più selettori di lavoro a un processo.
Allegati statici
In questo esempio, i criteri di classificazione vengono configurati con un allegato statico, che associa sempre il selettore di etichetta specificato a un processo.
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"))))));
Allegati condizionali
In questo esempio, i criteri di classificazione vengono configurati con un allegato condizionale. Valuta quindi una condizione rispetto alle etichette di processo per determinare se i selettori di etichetta devono essere associati al processo.
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")))))));
Allegati pass-through
In questo esempio, i criteri di classificazione sono configurati per collegare un selettore di lavoro ("Foo" = "<value comes from "Foo" label of the job>"
) al processo.
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))));
Allegati di allocazione ponderati
In questo esempio, i criteri di classificazione vengono configurati con un allegato di allocazione ponderato. Questo criterio divide i processi in base ai pesi specificati e allega i diversi selettori di conseguenza. In questo caso, il 30% dei posti di lavoro dovrebbe andare ai lavoratori con l'etichetta Vendor
impostata su A
e il 70% dovrebbe andare ai lavoratori con l'etichetta Vendor
impostata su 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"))
)))))));
Riclassificare un processo dopo l'invio
Dopo aver ricevuto e classificato un processo usando un criterio, è possibile riclassificarlo usando l'SDK. Nell'esempio seguente viene illustrato un modo per aumentare la priorità di Job su 10
, specificando semplicemente l'ID processo, chiamando il UpdateJobAsync
metodo e aggiornando classificationPolicyId e includendo l'etichettaHardware_VIP
.
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))));
Nota
Se le etichette del processo, queueId, channelId o selettori di lavoro vengono aggiornate, tutte le offerte esistenti nel processo vengono revocate e si riceve un evento RouterWorkerOfferRevoked per ogni offerta da EventGrid. Il processo viene ri codato e si riceve un evento RouterJobQueued . Le offerte di lavoro possono anche essere revocate quando la capacità totale di un lavoratore viene ridotta o i canali vengono aggiornati.