Méthode d’appariement des missions et des collaborateurs
Ce document décrit l’inscription des collaborateurs, l’envoi des missions et la manière dont ils sont associés les uns aux autres.
Inscription des collaborateurs
Pour qu’un travailleur puisse recevoir des offres pour traiter un travail, il doit d’abord être inscrit en définissant availableForOffers
la valeur true. Ensuite, nous devons spécifier les files d’attente sur lesquelles le worker écoute et les canaux qu’il peut gérer. Une fois inscrit, vous recevez un événement RouterWorkerRegistered d’Event Grid et l’état du worker est remplacé active
par .
Dans l’exemple suivant, nous inscrivons un worker dans :
- Écouter
queue-1
etqueue-2
. - Pouvoir gérer à la fois les canaux vocaux et de conversation. Dans ce cas, le collaborateur peut soit accepter une seule mission
voice
à la fois, soit deux missionschat
en même temps. Ce paramètre est configuré en spécifiant la capacité totale du worker et en affectant un coût par travail pour chaque canal. - Avoir un ensemble d’étiquettes décrivant des éléments du collaborateur qui pourraient aider à déterminer s’il correspond à une mission particulière.
var worker = await client.CreateWorkerAsync(new CreateWorkerOptions(workerId: "worker-1", capacity: 2)
{
AvailableForOffers = true,
Queues = { "queue1", "queue2" },
Channels =
{
new RouterChannel(channelId: "voice", capacityCostPerJob: 2),
new RouterChannel(channelId: "chat", capacityCostPerJob: 1)
},
Labels =
{
["Skill"] = new RouterValue(11),
["English"] = new RouterValue(true),
["French"] = new RouterValue(false),
["Vendor"] = new RouterValue("Acme")
}
});
let worker = await client.path("/routing/workers/{workerId}", "worker-1").patch({
body: {
availableForOffers: true,
capacity: 2,
queues: ["queue1", "queue2"],
channels: [
{ channelId: "voice", capacityCostPerJob: 2 },
{ channelId: "chat", capacityCostPerJob: 1 }
],
labels: {
Skill: 11,
English: true,
French: false,
Vendor: "Acme"
}
},
contentType: "application/merge-patch+json"
});
worker = client.upsert_worker(
worker_id = "worker-1",
available_for_offers = True,
capacity = 2,
queues = ["queue1", "queue2"],
channels = [
RouterChannel(channel_id = "voice", capacity_cost_per_job = 2),
RouterChannel(channel_id = "chat", capacity_cost_per_job = 1)
],
labels = {
"Skill": 11,
"English": True,
"French": False,
"Vendor": "Acme"
}
)
RouterWorker worker = client.createWorker(new CreateWorkerOptions("worker-1", 2)
.setAvailableForOffers(true)
.setQueues(List.of("queue1", "queue2"))
.setChannels(List.of(
new RouterChannel("voice", 2),
new RouterChannel("chat", 1)))
.setLabels(Map.of(
"Skill", new RouterValue(11),
"English", new RouterValue(true),
"French", new RouterValue(false),
"Vendor", new RouterValue("Acme"))));
Envoi de missions
Dans l’exemple suivant, nous envoyons un travail qui
- Va directement dans
queue1
. - Pour le canal
chat
. - Avec un sélecteur de travail qui spécifie que tout travail de maintenance de ce travail doit avoir une étiquette définie
English
true
sur . - Avec un sélecteur de travail qui spécifie que tout travail de maintenance de ce travail doit avoir une étiquette
Skill
supérieure10
à et que cette condition expire après une minute. - Avec une étiquette
name
définie surJohn
.
await client.CreateJobAsync(new CreateJobOptions("job1", "chat", "queue1")
{
RequestedWorkerSelectors =
{
new RouterWorkerSelector(key: "English", labelOperator: LabelOperator.Equal, value: new RouterValue(true)),
new RouterWorkerSelector(key: "Skill", labelOperator: LabelOperator.GreaterThan, value: new RouterValue(10))
{ ExpiresAfter = TimeSpan.FromMinutes(5) }
},
Labels = { ["name"] = new RouterValue("John") }
});
await client.path("/routing/jobs/{jobId}", "job1").patch({
body: {
channelId: "chat",
queueId: "queue1",
requestedWorkerSelectors: [
{ key: "English", labelOperator: "equal", value: true },
{ key: "Skill", labelOperator: "greaterThan", value: 10, expiresAfterSeconds: 300 },
],
labels: { name: "John" }
},
contentType: "application/merge-patch+json"
})
client.upsert_job(
job_id = "job1",
channel_id = "chat",
queue_id = "queue1",
requested_worker_selectors = [
RouterWorkerSelector(
key = "English",
label_operator = LabelOperator.EQUAL,
value = True
),
RouterWorkerSelector(
key = "Skill",
label_operator = LabelOperator.GREATER_THAN,
value = True,
expires_after_seconds = 300
)
],
labels = { "name": "John" }
)
client.createJob(new CreateJobOptions("job1", "chat", "queue1")
.setRequestedWorkerSelectors(List.of(
new RouterWorkerSelector("English", LabelOperator.EQUAL, new RouterValue(true)),
new RouterWorkerSelector("Skill", LabelOperator.GREATER_THAN, new RouterValue(10))
.setExpiresAfter(Duration.ofMinutes(5))))
.setLabels(Map.of("name", new RouterValue("John"))));
Le routeur de travaux tente de faire correspondre ce travail à un worker disponible à l’écoute queue1
du chat
canal, avec English
la valeur définie true
sur et Skill
supérieure à 10
.
Une fois la correspondance établie, une offre est créée. La stratégie de distribution attachée à la file d’attente contrôle le nombre d’offres actives qu’il peut y avoir pour un travail et la durée pendant laquelle chaque offre est valide. Vous recevez un événement OfferIssued qui ressemblerait à ceci :
{
"workerId": "worker-1",
"jobId": "7f1df17b-570b-4ae5-9cf5-fe6ff64cc712",
"channelId": "chat",
"queueId": "queue1",
"offerId": "525fec06-ab81-4e60-b780-f364ed96ade1",
"offerTimeUtc": "2021-06-23T02:43:30.3847144Z",
"expiryTimeUtc": "2021-06-23T02:44:30.3847674Z",
"jobPriority": 1,
"jobLabels": {
"name": "John"
}
}
L’événement OfferIssued inclut des détails sur le travail, le travailleur, la durée de validité de l’offre et le offerId
fait que vous devez accepter ou refuser le travail.
Remarque
La durée de vie maximale d’un travail est de 90 jours, après quoi il expire automatiquement.
Désinscription de worker
Si un worker souhaite arrêter la réception d’offres, il peut être désinscrit en définissant AvailableForOffers
false
ce paramètre lors de la mise à jour du worker et vous recevez un événement RouterWorkerDeregistered à partir d’Event Grid. Toutes les offres existantes pour le worker sont révoquées et vous recevez un événement RouterWorkerOfferRevoked pour chaque offre.
worker.AvailableForOffers = false;
worker = await client.UpdateWorkerAsync(worker);
worker = await client.path("/routing/workers/{workerId}", worker.body.id).patch({
body: { availableForOffers: false },
contentType: "application/merge-patch+json"
});
worker = client.upsert_worker(worker_id = worker.id, available_for_offers = False)
client.updateWorker(worker.getId(), BinaryData.fromObject(worker.setAvailableForOffers(false)), null);
Remarque
Si un travailleur est inscrit et inactif pendant plus de 7 jours, il est automatiquement désinscrit. Une fois l’inscription annulée, l’état du worker est draining
si un ou plusieurs travaux sont toujours attribués ou inactive
si aucun travail n’est affecté.