Aracılığıyla paylaş


Çalışanların en iyi çalışan dağıtım modu için derecelendiriliş şeklini özelleştirme

Dağıtım best-worker modu, önce işi en iyi şekilde işleyebilen çalışanları seçer. Çalışanları sıralama mantığı, iki çalışanı karşılaştırmak için bir ifade veya Azure işleviyle özelleştirilebilir. Aşağıdaki örnekte bu mantığın kendi Azure İşlevinizle nasıl özelleştirileceği gösterilmektedir.

Senaryo: En iyi çalışan dağıtım modunda özel puanlama kuralı

Teklifleri kuyrukla ilişkili çalışanları arasında dağıtmak istiyoruz. Çalışanlara etiketlerine ve beceri kümelerine göre bir puan verilecektir. En yüksek puana sahip çalışan ilk teklifi (BestWorker Dağıtım Modu) almalıdır.

Diagram showing Best Worker Distribution Mode problem statement

Durum

  • Bir iş oluşturuldu ve sınıflandırıldı.
    • İş, kendisiyle ilişkilendirilmiş aşağıdaki etiketlere sahiptir
      • ["CommunicationType"] = "Chat"
      • ["IssueType"] = "XboxSupport"
      • ["Language"] = "en"
      • ["HighPriority"] = true
      • ["SubIssueType"] = "ConsoleMalfunction"
      • ["ConsoleType"] = "XBOX_SERIES_X"
      • ["Model"] = "XBOX_SERIES_X_1TB"
    • İş, kendisiyle ilişkilendirilmiş aşağıdaki WorkerSelectors'a sahiptir
      • ["İngilizce"] >= 7
      • ["ChatSupport"] = true
      • ["XboxSupport"] = true
  • İş şu anda 'Kuyruğa Alındı' durumundadır; çalışanla eşleştirilmeyi bekleyen Xbox Donanım Destek Kuyruğu'nda sıralanmıştır.
  • Aynı anda birden çok çalışan kullanılabilir duruma gelir.
    • Çalışan 1 aşağıdaki etiketlerle oluşturulmuştur
      • ["HighPrioritySupport"] = true
      • ["HardwareSupport"] = true
      • ["Support_XBOX_SERIES_X"] = true
      • ["english"] = 10
      • ["ChatSupport"] = true
      • ["XboxSupport"] = true
    • Çalışan 2 aşağıdaki etiketlerle oluşturulmuştur
      • ["HighPrioritySupport"] = true
      • ["HardwareSupport"] = true
      • ["Support_XBOX_SERIES_X"] = true
      • ["Support_XBOX_SERIES_S"] = true
      • ["İngilizce"] = 8
      • ["ChatSupport"] = true
      • ["XboxSupport"] = true
    • Çalışan 3 aşağıdaki etiketlerle oluşturulmuştur
      • ["HighPrioritySupport"] = false
      • ["HardwareSupport"] = true
      • ["Support_XBOX"] = true
      • ["İngilizce"] = 7
      • ["ChatSupport"] = true
      • ["XboxSupport"] = true

Beklenti

Çalışanların ilk teklifi hangi çalışanın alacağını seçmesi için puanlama yaparken aşağıdaki davranışın geçerli olmasını istiyoruz.

Decision flow diagram for scoring worker

Karar akışı (yukarıda gösterildiği gibi) aşağıdaki gibidir:

  • bir iş YüksekFiyat DEĞİlse:

    • Etiketli çalışanlar: ["Support_XBOX"] = true; 100 puan alır
    • Aksi takdirde 1 puan alır
  • bir iş HighPriority ise:

    • Etiketli çalışanlar: ["HighPrioritySupport"] = false; 1 puanı alın
    • Aksi takdirde, if ["HighPrioritySupport"] = true:
      • Çalışan konsol türü konusunda uzman mı -> Çalışanın etiketi var mı: ["Support_<jobLabels.ConsoleType>"] = true? Doğruysa, çalışan 200 puan alır
      • Aksi takdirde 100 puan alır

Azure işlevi oluşturma

Süreci daha ileriye taşımadan önce çalışan puanlayan bir Azure işlevi tanımlamamıza izin verin.

Dekont

Aşağıdaki Azure işlevi JavaScript'i kullanıyor. Daha fazla bilgi için bkz. Hızlı Başlangıç: Visual Studio Code kullanarak Azure'da JavaScript işlevi oluşturma

Çalışan 1 için örnek giriş

{
  "job": {
    "CommunicationType": "Chat",
    "IssueType": "XboxSupport",
    "Language": "en",
    "HighPriority": true,
    "SubIssueType": "ConsoleMalfunction",
    "ConsoleType": "XBOX_SERIES_X",
    "Model": "XBOX_SERIES_X_1TB"
  },
  "selectors": [
    {
      "key": "English",
      "operator": "GreaterThanEqual",
      "value": 7,
      "expiresAfterSeconds": null
    },
    {
      "key": "ChatSupport",
      "operator": "Equal",
      "value": true,
      "expiresAfterSeconds": null
    },
    {
      "key": "XboxSupport",
      "operator": "Equal",
      "value": true,
      "expiresAfterSeconds": null
    }
  ],
  "worker": {
    "Id": "e3a3f2f9-3582-4bfe-9c5a-aa57831a0f88",
    "HighPrioritySupport": true,
    "HardwareSupport": true,
    "Support_XBOX_SERIES_X": true,
    "English": 10,
    "ChatSupport": true,
    "XboxSupport": true
  }
}

Örnek uygulama:

module.exports = async function (context, req) {
    context.log('Best Worker Distribution Mode using Azure Function');

    let score = 0;
    const jobLabels = req.body.job;
    const workerLabels = req.body.worker;

    const isHighPriority = !!jobLabels["HighPriority"];
    context.log('Job is high priority? Status: ' + isHighPriority);

    if(!isHighPriority) {
        const isGenericXboxSupportWorker = !!workerLabels["Support_XBOX"];
        context.log('Worker provides general xbox support? Status: ' + isGenericXboxSupportWorker);

        score = isGenericXboxSupportWorker ? 100 : 1;

    } else {
        const workerSupportsHighPriorityJob = !!workerLabels["HighPrioritySupport"];
        context.log('Worker provides high priority support? Status: ' + workerSupportsHighPriorityJob);

        if(!workerSupportsHighPriorityJob) {
            score = 1;
        } else {
            const key = `Support_${jobLabels["ConsoleType"]}`;
            
            const workerSpecializeInConsoleType = !!workerLabels[key];
            context.log(`Worker specializes in consoleType: ${jobLabels["ConsoleType"]} ? Status: ${workerSpecializeInConsoleType}`);

            score = workerSpecializeInConsoleType ? 200 : 100;
        }
    }
    context.log('Final score of worker: ' + score);

    context.res = {
        // status: 200, /* Defaults to 200 */
        body: score
    };
}

Çalışan 1 için Çıkış

200

Yukarıda belirtilen uygulamayla, verilen iş için çalışanlar için aşağıdaki puanları alacağız:

Çalışan Puan
Çalışan 1 200
Çalışan 2 200
Çalışan 3 1

Teklifleri en iyi çalışan moduna göre dağıtma

Azure işlev uygulaması hazır olduğuna göre, Yönlendirici SDK'sını kullanarak BestWorkerDistribution modunun bir örneğini oluşturalım.

var administrationClient = new JobRouterAdministrationClient("<YOUR_ACS_CONNECTION_STRING>");

// Setup Distribution Policy
var distributionPolicy = await administrationClient.CreateDistributionPolicyAsync(
    new CreateDistributionPolicyOptions(
        distributionPolicyId: "BestWorkerDistributionMode",
        offerExpiresAfter: TimeSpan.FromMinutes(5),
        mode: new BestWorkerMode(scoringRule: new FunctionRouterRule(new Uri("<insert function url>")))
    ) { Name = "XBox hardware support distribution" });

// Setup Queue
var queue = await administrationClient.CreateQueueAsync(
    new CreateQueueOptions(
        queueId: "XBox_Hardware_Support_Q",
        distributionPolicyId: distributionPolicy.Value.Id
    ) { Name = "XBox Hardware Support Queue" });

// Create workers
var worker1 = await client.CreateWorkerAsync(new CreateWorkerOptions(workerId: "Worker_1", capacity: 100)
    {
        Queues = { queue.Value.Id },
        Channels = { new RouterChannel(channelId: "Xbox_Chat_Channel", capacityCostPerJob: 10) },
        Labels =
        {
            ["English"] = new RouterValue(10),
            ["HighPrioritySupport"] = new RouterValue(true),
            ["HardwareSupport"] = new RouterValue(true),
            ["Support_XBOX_SERIES_X"] = new RouterValue(true),
            ["ChatSupport"] = new RouterValue(true),
            ["XboxSupport"] = new RouterValue(true)
        }
    });

var worker2 = await client.CreateWorkerAsync(new CreateWorkerOptions(workerId: "Worker_2", capacity: 100)
    {
        Queues = { queue.Value.Id },
        Channels = { new RouterChannel(channelId: "Xbox_Chat_Channel", capacityCostPerJob: 10) },
        Labels =
        {
            ["English"] = new RouterValue(8),
            ["HighPrioritySupport"] = new RouterValue(true),
            ["HardwareSupport"] = new RouterValue(true),
            ["Support_XBOX_SERIES_X"] = new RouterValue(true),
            ["ChatSupport"] = new RouterValue(true),
            ["XboxSupport"] = new RouterValue(true)
        }
    });

var worker3 = await client.CreateWorkerAsync(new CreateWorkerOptions(workerId: "Worker_3", capacity: 100)
    {
        Queues = { queue.Value.Id },
        Channels = { new RouterChannel(channelId: "Xbox_Chat_Channel", capacityCostPerJob: 10) },
        Labels =
        {
            ["English"] = new RouterValue(7),
            ["HighPrioritySupport"] = new RouterValue(true),
            ["HardwareSupport"] = new RouterValue(true),
            ["Support_XBOX_SERIES_X"] = new RouterValue(true),
            ["ChatSupport"] = new RouterValue(true),
            ["XboxSupport"] = new RouterValue(true)
        }
    });

// Create Job
var job = await client.CreateJobAsync(
    new CreateJobOptions(jobId: "job1", channelId: "Xbox_Chat_Channel", queueId: queue.Value.Id)
    {
        Priority = 100,
        ChannelReference = "ChatChannel",
        RequestedWorkerSelectors =
        {
            new RouterWorkerSelector(key: "English", labelOperator: LabelOperator.GreaterThanEqual, value: new RouterValue(7)),
            new RouterWorkerSelector(key: "ChatSupport", labelOperator: LabelOperator.Equal, value: new RouterValue(true)),
            new RouterWorkerSelector(key: "XboxSupport", labelOperator: LabelOperator.Equal, value: new RouterValue(true))
        },
        Labels =
        {
            ["CommunicationType"] = new RouterValue("Chat"),
            ["IssueType"] = new RouterValue("XboxSupport"),
            ["Language"] = new RouterValue("en"),
            ["HighPriority"] = new RouterValue(true),
            ["SubIssueType"] = new RouterValue("ConsoleMalfunction"),
            ["ConsoleType"] = new RouterValue("XBOX_SERIES_X"),
            ["Model"] = new RouterValue("XBOX_SERIES_X_1TB")
        }
    });

// Wait a few seconds and see which worker was matched
await Task.Delay(TimeSpan.FromSeconds(5));
var getJob = await client.GetJobAsync(job.Value.Id);
Console.WriteLine(getJob.Value.Assignments.Select(assignment => assignment.Value.WorkerId).First());

Çıktı

Worker_1 // or Worker_2

Since both workers, Worker_1 and Worker_2, get the same score of 200,
the worker who has been idle the longest will get the first offer.