ジョブとワーカーの照合方法

このドキュメントでは、ワーカーの登録、ジョブの送信、およびそれらが相互にどのように一致しているかについて説明します。

ワーカー登録

ワーカーは、ジョブ提供のためのプランを受け取ることができる前に、最初に availableForOffers を true に設定することで登録されている必要があります。 次に、ワーカーがリッスンするキューと処理できるチャネルを指定する必要があります。 登録されると、Event Grid から RouterWorkerRegistered イベントが受信され、ワーカーの状態が active に変更されます。

次の例では、以下のためにワーカーを登録します。

  • queue-1queue-2 でリッスンする
  • 音声とチャットの両方のチャネルを処理できるようにします。 この場合、ワーカーは一度に1つの voiceジョブを実行することも、2つの chatジョブを同時に実行することもできます。 この設定は、ワーカーの総容量を指定し、各チャネルにジョブあたりのコストを割り当てることによって構成されます。
  • 特定のジョブに対して一致するかどうかを判断するのに役立つ、ワーカーについて説明するラベルのセットを用意します。
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"))));

ジョブの送信

次の例では、以下のジョブを送信します

  • queue1 に直接移動します。
  • chat チャネルについて。
  • このジョブにサービスを提供するすべてのワーカーの English ラベルを true に設定する必要があることを指定するワーカー セレクターを使用。
  • このジョブにサービスを提供するすべてのワーカーの Skill ラベルが 10 より大きく、この条件が 1 分後に期限切れになるように指定するワーカー セレクターを使用。
  • John に設定した name のラベルを使用。
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"))));

ジョブ ルーターは、Englishtrue に設定され、Skill10 より大きい chat チャネルの queue1 でリッスンしている使用可能なワーカーとこのジョブを照合しようとします。 照合が行われると、プランが作成されます。 キューにアタッチされているディストリビューション ポリシーによって、ジョブに使用できるアクティブなプランの数と、各プランの有効期間が制御されます。 次のような OfferIssued イベント表示されます。

{
    "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"
    }
}

OfferIssued イベントには、ジョブ、ワーカー、プランの有効期間、およびジョブを受け入れるか拒否する必要がある offerId に関する詳細が含まれます。

Note

ジョブの最長有効期間は 90 日で、その後は自動的に期限切れになります。

ワーカーの登録解除

ワーカーがプランの受け取りを停止する必要がある場合、ワーカーの更新時に AvailableForOffersfalse に設定して登録を解除でき、Event Grid から RouterWorkerDeregistered イベントを受け取ります。 ワーカーの既存のプランはすべて取り消され、プランごとに RouterWorkerOfferRevoked イベントを受け取ります。

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

Note

ワーカーが登録され、7 日を超えてアイドル状態になっている場合は、自動的に登録解除されます。 登録が解除されると、1 つ以上のジョブがまだ割り当てられている場合はワーカーの状態が draining になり、ジョブが割り当てられていない場合は inactive になります。