Initial implementation of procfile

Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
2024-12-23 14:52:23 +00:00
parent b4b96b3f4e
commit 09dd248d24
33 changed files with 343 additions and 311 deletions

View File

@@ -0,0 +1,38 @@
using Pushy.Domain;
namespace Pushy.Silo.Grains;
public sealed class LinkGenerator : IGrainBase, ILinkGenerator
{
private readonly ILogger<LinkGenerator> _logger;
private readonly IClusterClient _clusterClient;
public IGrainContext GrainContext { get; }
public LinkGenerator(
IGrainContext grainContext,
IClusterClient clusterClient,
ILogger<LinkGenerator> logger)
{
_clusterClient = clusterClient;
_logger = logger;
GrainContext = grainContext;
}
public async ValueTask<LinkResult> GenerateTextShare(string text)
{
string item = $"{Guid.CreateVersion7():N}"[9..];
var textGrain = _clusterClient.GetGrain<ITextItem>(item);
try
{
await textGrain.SetText(text);
return new LinkResult(textGrain);
}
catch (Exception)
{
//TODO: Write log message of why it fails?
//Swallow small change of error
return await GenerateTextShare(text);
}
}
}

View File

@@ -0,0 +1,67 @@
using Pushy.Domain;
namespace Pushy.Silo.Grains;
public sealed class TextItemGrain : IGrainBase, ITextItem, IRemindable
{
private readonly IPersistentState<TextItem> _state;
private readonly ILogger<TextItemGrain> _logger;
private IGrainReminder? _reminder;
public TextItemGrain(
IGrainContext grainContext,
[PersistentState("text")] IPersistentState<TextItem> state,
ILogger<TextItemGrain> logger)
{
_state = state;
_logger = logger;
GrainContext = grainContext;
}
public IGrainContext GrainContext { get; }
/// <inheritdoc />
public async Task OnActivateAsync(CancellationToken cancellationToken)
{
_reminder = await this.RegisterOrUpdateReminder("clear", TimeSpan.FromDays(10), TimeSpan.FromDays(10));
}
/// <inheritdoc />
public async ValueTask<TextSetResult> SetText(string text)
{
try
{
if (_state.State.Text is not null)
return TextSetResult.Failure;
_state.State.Text = text;
await _state.WriteStateAsync();
return TextSetResult.Success;
}
catch (Exception)
{
return TextSetResult.Failure;
}
}
/// <inheritdoc />
public ValueTask<string> GetText()
{
return ValueTask.FromResult(_state.State.Text ?? throw new InvalidOperationException("No text was available"));
}
/// <inheritdoc />
public async Task ReceiveReminder(string reminderName, TickStatus status)
{
if (reminderName == "clear")
{
_state.State.Text = null;
await _state.WriteStateAsync();
this.DeactivateOnIdle();
_logger.LogInformation("Text item have been cleared!");
}
}
}

28
Pushy.Silo/Program.cs Normal file
View File

@@ -0,0 +1,28 @@
using StackExchange.Redis;
var builder = Host.CreateApplicationBuilder(args);
builder.UseOrleans(silo =>
{
silo.AddActivityPropagation();
silo.UseRedisClustering(builder.Configuration.GetConnectionString("Valkey")!);
silo.UseRedisReminderService(conf =>
{
ConfigurationOptions configurationOptions =
ConfigurationOptions.Parse(builder.Configuration.GetConnectionString("Valkey")!);
configurationOptions.DefaultDatabase = 0;
conf.ConfigurationOptions = configurationOptions;
});
silo.AddRedisGrainStorageAsDefault(options =>
{
ConfigurationOptions configurationOptions = ConfigurationOptions.Parse(builder.Configuration.GetConnectionString("Valkey")!);
configurationOptions.DefaultDatabase = 1;
options.ConfigurationOptions = configurationOptions;
});
});
builder.Services.AddAllElasticApm();
var host = builder.Build();
host.Run();

View File

@@ -0,0 +1,12 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"Pushy.Silo": {
"commandName": "Project",
"dotnetRunMessages": true,
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-Pushy.Silo-607fe096-6d3f-44f4-8e5d-8a2c875f8758</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<Title>Pushy Silo</Title>
<Authors>Henrik Lassen</Authors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Elastic.Apm.NetCoreAll" Version="1.31.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0"/>
<PackageReference Include="Microsoft.Orleans.Clustering.Redis" Version="9.0.1" />
<PackageReference Include="Microsoft.Orleans.Persistence.Redis" Version="9.0.1" />
<PackageReference Include="Microsoft.Orleans.Reminders.Redis" Version="9.0.1" />
<PackageReference Include="Microsoft.Orleans.Server" Version="9.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pushy.Domain\Pushy.Domain.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

View File

@@ -0,0 +1,11 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ElasticApm": {
"ServerUrl": "http://apm.home.local:8200"
}
}