Initial Commit

This commit is contained in:
Harald Wolff 2024-09-30 00:12:30 +02:00
commit 5eef44b30f
4 changed files with 148 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
bin
obj

63
WebTask.cs Normal file
View file

@ -0,0 +1,63 @@
using ln.http;
namespace ln.web.tasks;
public class WebTask
{
public event Action<WebTask> TaskFinished;
private WebTaskApi _webTaskApi;
private Func<WebTask, HttpResponse>? _action;
private HttpResponse? _httpResponse;
public HttpResponse HttpResponse => _httpResponse;
public Guid Id { get; }
protected WebTask(WebTaskApi webTaskApi)
{
Id = Guid.NewGuid();
Label = Id.ToString();
_webTaskApi = webTaskApi;
_action = null;
Progress = Double.NaN;
}
public WebTask(WebTaskApi webTaskApi, Func<WebTask, HttpResponse> action) :this(webTaskApi)
{
_action = action;
}
public bool Finished { get; private set; }
public WebTask Start()
{
Finished = false;
if (_action is not null)
ThreadPool.QueueUserWorkItem((o) =>
{
try
{
Progress = 0.0;
_httpResponse = _action(this);
Progress = 1.0;
}
catch (Exception e)
{
Progress = 1.0;
_httpResponse = HttpResponse.InternalServerError().Content(e);
}
finally
{
Finished = true;
ThreadPool.QueueUserWorkItem((o) => TaskFinished?.Invoke(this));
}
});
return this;
}
public string Label { get; set; }
public double Progress { get; set; }
}

66
WebTaskApi.cs Normal file
View file

@ -0,0 +1,66 @@
using ln.http;
using Newtonsoft.Json.Linq;
using HttpMethod = ln.http.HttpMethod;
namespace ln.web.tasks;
public class WebTaskApi : HttpEndpointController
{
private Dictionary<Guid, WebTask> _tasks = new Dictionary<Guid, WebTask>();
public WebTaskApi(HttpRouter parentRouter) :base(parentRouter)
{
}
public HttpResponse EnqueueTask(string label, Func<WebTask, HttpResponse> taskAction)
{
WebTask webTask = new WebTask(this, taskAction);
webTask.Label = label;
lock (this)
_tasks.Add(webTask.Id, webTask);
webTask.Start();
return HttpResponse.SeeOther("/v1/tasks/" + webTask.Id.ToString());
}
[Map(HttpMethod.ANY,
"/v1/tasks/(?<taskId>[0-9A-Fa-f]{8}[-]?[0-9A-Fa-f]{4}[-]?[0-9A-Fa-f]{4}[-]?[0-9A-Fa-f]{4}[-]?[0-9A-Fa-f]{12}[-]?)$")]
public HttpResponse GetWebTask(
[Route]Guid taskId
){
if (_tasks.TryGetValue(taskId, out var webTask))
{
if (webTask.HttpResponse is HttpResponse)
return webTask.HttpResponse;
if (!webTask.Finished)
return HttpResponse.NoContent().Header("X-Task-Progress", webTask.Progress.ToString("F"));
return HttpResponse.OK();
}
return HttpResponse.NotFound();
}
[Map(HttpMethod.GET,"/v1/tasks$")]
public HttpResponse GetTasks()
{
JArray taskList = new JArray();
lock (this)
{
foreach (var webTask in _tasks.Values)
{
JObject taskState = new JObject();
taskState.Add("id", webTask.Id.ToString());
taskState.Add("label", webTask.Label);
taskState.Add("progress", webTask.Progress);
taskState.Add("finished", webTask.Finished);
taskList.Add(taskState);
}
}
return HttpResponse.OK().Content(taskList);
}
}

17
ln.web.tasks.csproj Normal file
View file

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ln.http" Version="0.10.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ln.http\ln.http\ln.http.csproj" />
</ItemGroup>
</Project>