Last active
September 23, 2021 06:31
-
-
Save runceel/d975f3e92975b98cd638d25e98fe3776 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var dataService = new DataService(); | |
dataService.AddWorker(new Worker(1)); | |
dataService.AddWorker(new Worker(2)); | |
dataService.AddWorker(new Worker(3)); | |
dataService.AddWorker(new Worker(4)); | |
var frontend1 = new FrontendInfo("tsushi01", "FE1"); | |
var frontend2 = new FrontendInfo("tsushi02", "FE2"); | |
// 適当に空いてるワーカーを返してもらう | |
Console.WriteLine(dataService.GetAvailableWorker(frontend1)); | |
Console.WriteLine(dataService.GetAvailableWorker(frontend2)); | |
// 再要求しても同じワーカーが返ってくるはず | |
Console.WriteLine(dataService.GetAvailableWorker(frontend1)); | |
Console.WriteLine(dataService.GetAvailableWorker(frontend2)); | |
record Worker(int Id); | |
record FrontendInfo(string HostName, string FrontEnd); | |
class DataService | |
{ | |
// ロック用 | |
private readonly object _syncRoot = new(); | |
// 誰も使ってないワーカー管理 | |
private readonly Queue<Worker> _availableWorkers= new(); | |
// フロントエンドに割り当て済みのワーカー管理 | |
private readonly Dictionary<FrontendInfo, Worker> _assignedWorkers = new(); | |
public Worker? GetAvailableWorker(FrontendInfo frontend) | |
{ | |
lock(_syncRoot) | |
{ | |
var worker = GetWorkerForFrontend(frontend); | |
if (worker == null) | |
{ | |
worker = AssignWorker(frontend); | |
} | |
return worker; | |
} | |
} | |
// Frontend がワーカーが不要になったときに返却 | |
public void ReleaseWorker(FrontendInfo frontend) | |
{ | |
lock(_syncRoot) | |
{ | |
if (_assignedWorkers.TryGetValue(frontend, out var worker)) | |
{ | |
_assignedWorkers.Remove(frontend); | |
_availableWorkers.Append(worker); | |
} | |
} | |
} | |
// データサービスが管理する Worker を追加 | |
public void AddWorker(Worker worker) | |
{ | |
lock(_syncRoot) | |
{ | |
_availableWorkers.Append(worker); | |
} | |
} | |
// 誰も使ってない Worker を Frontend に割り当てる | |
private Worker? AssignWorker(FrontendInfo frontend) | |
{ | |
if (_availableWorkers.Count == 0) | |
{ | |
return null; | |
} | |
var worker = _availableWorkers.Dequeue(); | |
_assignedWorkers.Add(frontend, worker); | |
return worker; | |
} | |
// Frontend に対して既に割り当て済みの Worker があったらそれを返す | |
private Worker? GetWorkerForFrontend(FrontendInfo frontend) | |
{ | |
_ = _assignedWorkers.TryGetValue(frontend, out var worker); | |
return worker; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment