Partage via


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é activepar .

Dans l’exemple suivant, nous inscrivons un worker dans :

  • Écouter queue-1 et queue-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 missions chat 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 truesur .
  • Avec un sélecteur de travail qui spécifie que tout travail de maintenance de ce travail doit avoir une étiquette Skill supérieure 10 à et que cette condition expire après une minute.
  • Avec une étiquette name définie sur John.
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é.