fix: queue client && inmemory repository
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using InServiceQue.Core.Models;
|
using InServiceQue.Core.Models;
|
||||||
using InServiceQue.Core.Repositories;
|
using InServiceQue.Core.Repositories;
|
||||||
@@ -7,32 +6,32 @@ namespace InServiceQue.InMemory;
|
|||||||
|
|
||||||
public class TaskRepositoryInMemory: ITaskRepository
|
public class TaskRepositoryInMemory: ITaskRepository
|
||||||
{
|
{
|
||||||
//todo: concurrent access here
|
private static object _lockObject = new();
|
||||||
private static int _currentShard;
|
private static int _currentShard;
|
||||||
private static ConcurrentDictionary<string, ConcurrentQueue<QueueTask>> _quesByType = new();
|
private static Dictionary<string, Queue<QueueTask>> _quesByType = new();
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// TODO release managed resources here
|
// TODO release managed resources here
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Insert(QueueTask task)
|
public void Insert(QueueTask task)
|
||||||
|
{
|
||||||
|
lock (_lockObject)
|
||||||
{
|
{
|
||||||
if (_quesByType.ContainsKey(task.TaskType))
|
if (_quesByType.ContainsKey(task.TaskType))
|
||||||
{
|
{
|
||||||
_quesByType.AddOrUpdate(task.TaskType,
|
_quesByType[task.TaskType].Enqueue(task);
|
||||||
(t) => new ConcurrentQueue<QueueTask>(new[] { task }),
|
|
||||||
(t, queue) =>
|
|
||||||
{
|
|
||||||
queue.Enqueue(task);
|
|
||||||
return queue;
|
|
||||||
}
|
}
|
||||||
);
|
else
|
||||||
|
{
|
||||||
|
_quesByType.Add(task.TaskType, new Queue<QueueTask>(new []{task}));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InsertAsync(QueueTask task)
|
public async Task InsertAsync(QueueTask task)
|
||||||
{
|
{
|
||||||
|
|
||||||
Insert(task);
|
Insert(task);
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@@ -84,26 +83,27 @@ public class TaskRepositoryInMemory: ITaskRepository
|
|||||||
public QueueTask? GetNextTaskRolling()
|
public QueueTask? GetNextTaskRolling()
|
||||||
{
|
{
|
||||||
QueueTask? task = null;
|
QueueTask? task = null;
|
||||||
|
lock (_lockObject)
|
||||||
|
{
|
||||||
var topicsCount = _quesByType.Count;
|
var topicsCount = _quesByType.Count;
|
||||||
for (int i = 0; i < topicsCount; i++)
|
for (int i = 0; i < topicsCount; i++)
|
||||||
{
|
{
|
||||||
//todo: concurrent access
|
|
||||||
if (i == _currentShard)
|
if (i == _currentShard)
|
||||||
{
|
{
|
||||||
var keyValuePair = _quesByType.ToArray()[i];
|
var keyValuePair = _quesByType.ToArray()[i];
|
||||||
var que = keyValuePair.Value;
|
var que = keyValuePair.Value;
|
||||||
que.TryDequeue(out task);
|
task = que.Dequeue();
|
||||||
|
|
||||||
if (que.IsEmpty)
|
if (!que.Any())
|
||||||
{
|
{
|
||||||
_quesByType.TryRemove(keyValuePair);
|
_quesByType.Remove(keyValuePair.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//todo: concurrent access
|
|
||||||
_currentShard = _currentShard == topicsCount - 1 ? 0 : _currentShard + 1;
|
_currentShard = _currentShard == topicsCount - 1 ? 0 : _currentShard + 1;
|
||||||
|
}
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
@@ -116,10 +116,14 @@ public class TaskRepositoryInMemory: ITaskRepository
|
|||||||
return await Task.FromResult(GetNextTaskRolling());
|
return await Task.FromResult(GetNextTaskRolling());
|
||||||
|
|
||||||
QueueTask? task = null;
|
QueueTask? task = null;
|
||||||
|
lock (_lockObject)
|
||||||
|
{
|
||||||
if (_quesByType.TryGetValue(taskType, out var que))
|
if (_quesByType.TryGetValue(taskType, out var que))
|
||||||
{
|
{
|
||||||
que.TryDequeue(out task);
|
que.TryDequeue(out task);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return await Task.FromResult(task);
|
return await Task.FromResult(task);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using InServiceQue.Core.Repositories;
|
|||||||
using InServiceQue.InMemory;
|
using InServiceQue.InMemory;
|
||||||
using InServiceQue.Sample;
|
using InServiceQue.Sample;
|
||||||
using InServiceQue.Services;
|
using InServiceQue.Services;
|
||||||
|
using Microsoft.AspNetCore.Http.HttpResults;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
@@ -15,13 +16,19 @@ builder.Services.AddInServiceQue(builder =>
|
|||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
app.MapGet("/", async (string msg) =>
|
app.MapGet("/", async (string msg) =>
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(msg))
|
||||||
{
|
{
|
||||||
var taskRepository = app.Services.GetService<IQueueClient>();
|
var taskRepository = app.Services.GetService<IQueueClient>();
|
||||||
await taskRepository.AddTaskAsync(new QueueTask(new SendMessageTask(new SendMessagePayload()
|
await taskRepository.AddTaskAsync(new SendMessageTask(new SendMessagePayload()
|
||||||
{
|
{
|
||||||
From = "John", To = "Esther", Message = msg
|
From = "John", To = "Esther", Message = msg
|
||||||
})));
|
}));
|
||||||
await taskRepository.AddTaskAsync(new QueueTask(new OtherMessageTask(msg)));
|
await taskRepository.AddTaskAsync(new OtherMessageTask(msg));
|
||||||
|
|
||||||
|
return new OkResult();
|
||||||
|
}
|
||||||
|
|
||||||
return new OkResult();
|
return new OkResult();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ public class QueueClient: IQueueClient
|
|||||||
{
|
{
|
||||||
private readonly ITaskRepository _repository;
|
private readonly ITaskRepository _repository;
|
||||||
|
|
||||||
|
public QueueClient(ITaskRepository repository)
|
||||||
|
{
|
||||||
|
_repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
public void AddTask(IQueueTask task)
|
public void AddTask(IQueueTask task)
|
||||||
{
|
{
|
||||||
var queueTask = new QueueTask(task);
|
var queueTask = new QueueTask(task);
|
||||||
|
|||||||
Reference in New Issue
Block a user