Skip to content

Commit

Permalink
Upgrade to foundatio 11 and Microsoft TimeProvider (#1680)
Browse files Browse the repository at this point in the history
* Upgrade foundatio

* More time provider work

* WIP - Time provider

revert settings

Revert log

PR feedback

Fixed di issue

PR Feedback
  • Loading branch information
niemyjski authored Sep 10, 2024
1 parent 4e1766e commit dacf97b
Show file tree
Hide file tree
Showing 129 changed files with 1,460 additions and 1,143 deletions.
36 changes: 22 additions & 14 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.json]
insert_final_newline = false

# Generated code
[*{_AssemblyInfo.cs,.notsupported.cs,AsmOffsets.cs}]
generated_code = true
Expand All @@ -34,25 +31,25 @@ csharp_new_line_between_query_expression_clauses = true
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_case_contents_when_block = false
csharp_indent_switch_labels = true
csharp_indent_labels = one_less_than_current

# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:suggestion

# avoid this. unless absolutely necessary
dotnet_style_qualification_for_field = false:error
dotnet_style_qualification_for_property = false:error
dotnet_style_qualification_for_method = false:error
dotnet_style_qualification_for_event = false:error
# dotnet_style_qualification_for_field = false:suggestion
# dotnet_style_qualification_for_property = false:suggestion
# dotnet_style_qualification_for_method = false:suggestion
# dotnet_style_qualification_for_event = false:suggestion

# Types: use keywords instead of BCL types, and permit var only when the type is clear
csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_when_type_is_apparent = false:none
csharp_style_var_elsewhere = true:suggestion
# csharp_style_var_elsewhere = false:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = false:suggestion
# dotnet_style_predefined_type_for_member_access = true:suggestion

# name all constant fields using PascalCase
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
Expand All @@ -63,7 +60,7 @@ dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_style.pascal_case_style.capitalization = pascal_case

# static fields should have s_ prefix
dotnet_naming_rule.static_fields_should_have_prefix.severity = false:none
# dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
dotnet_naming_symbols.static_fields.applicable_kinds = field
Expand Down Expand Up @@ -95,6 +92,7 @@ dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_collection_expression = when_types_exactly_match
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
Expand Down Expand Up @@ -154,9 +152,8 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false

# Custom
csharp_style_namespace_declarations = file_scoped:error
dotnet_diagnostic.IDE0005.severity = error # Using directive is unnecessary.
# License header
# file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.

# C++ Files
[*.{cpp,h,in}]
Expand Down Expand Up @@ -191,3 +188,14 @@ indent_size = 2
end_of_line = lf
[*.{cmd,bat}]
end_of_line = crlf

# Custom
csharp_style_namespace_declarations = file_scoped:error
csharp_style_var_elsewhere = true:suggestion
dotnet_diagnostic.IDE0005.severity = error # Using directive is unnecessary.
dotnet_naming_rule.static_fields_should_have_prefix.severity = false:none
dotnet_style_predefined_type_for_member_access = false:suggestion
dotnet_style_qualification_for_field = false:error
dotnet_style_qualification_for_property = false:error
dotnet_style_qualification_for_method = false:error
dotnet_style_qualification_for_event = false:error
2 changes: 1 addition & 1 deletion .github/workflows/build-arm64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
run: "echo ref: ${{github.ref}} event: ${{github.event_name}}"
- name: Build Version
run: |
dotnet tool install --global minver-cli --version 5.0.0
dotnet tool install --global minver-cli --version 6.0.0
version=$(minver --tag-prefix v)
echo "MINVERVERSIONOVERRIDE=$version" >> $GITHUB_ENV
echo "VERSION=$version" >> $GITHUB_ENV
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
- name: Version
id: version
run: |
dotnet tool install --global minver-cli --version 5.0.0
dotnet tool install --global minver-cli --version 6.0.0
version=$(minver --tag-prefix v)
echo "version=$version" >> $GITHUB_OUTPUT
echo "### $version" >> $GITHUB_STEP_SUMMARY
Expand Down
4 changes: 2 additions & 2 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<ReferenceFoundatioSource>false</ReferenceFoundatioSource>
<ReferenceFoundatioRepositoriesSource>false</ReferenceFoundatioRepositoriesSource>
<FoundatioVersion>10.7.1</FoundatioVersion>
<FoundatioVersion>11.0.2</FoundatioVersion>
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All"/>
<PackageReference Include="AsyncFixer" Version="1.6.0" PrivateAssets="All" />
<PackageReference Include="MinVer" Version="5.0.0" PrivateAssets="All" />
<PackageReference Include="MinVer" Version="6.0.0" PrivateAssets="All" />
</ItemGroup>
</Project>
11 changes: 6 additions & 5 deletions src/Exceptionless.Core/Billing/BillingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Exceptionless.Core.Models;
using Exceptionless.Core.Models.Billing;
using Exceptionless.Core.Repositories;
using Foundatio.Utility;

namespace Exceptionless.Core.Billing;

Expand All @@ -12,13 +11,15 @@ public class BillingManager
private readonly IProjectRepository _projectRepository;
private readonly IUserRepository _userRepository;
private readonly BillingPlans _plans;
private readonly TimeProvider _timeProvider;

public BillingManager(IOrganizationRepository organizationRepository, IProjectRepository projectRepository, IUserRepository userRepository, BillingPlans plans)
public BillingManager(IOrganizationRepository organizationRepository, IProjectRepository projectRepository, IUserRepository userRepository, BillingPlans plans, TimeProvider timeProvider)
{
_organizationRepository = organizationRepository;
_projectRepository = projectRepository;
_userRepository = userRepository;
_plans = plans;
_timeProvider = timeProvider;
}

public async Task<bool> CanAddOrganizationAsync(User? user)
Expand Down Expand Up @@ -98,7 +99,7 @@ public void ApplyBillingPlan(Organization organization, BillingPlan plan, User?
organization.PlanId = plan.Id;
organization.PlanName = plan.Name;
organization.PlanDescription = plan.Description;
organization.BillingChangeDate = SystemClock.UtcNow;
organization.BillingChangeDate = _timeProvider.GetUtcNow().UtcDateTime;

if (updateBillingPrice)
organization.BillingPrice = plan.Price;
Expand All @@ -112,13 +113,13 @@ public void ApplyBillingPlan(Organization organization, BillingPlan plan, User?
organization.MaxEventsPerMonth = plan.MaxEventsPerMonth;
organization.HasPremiumFeatures = plan.HasPremiumFeatures;

organization.GetCurrentUsage().Limit = organization.GetMaxEventsPerMonthWithBonus();
organization.GetCurrentUsage(_timeProvider).Limit = organization.GetMaxEventsPerMonthWithBonus(_timeProvider);
}

public void ApplyBonus(Organization organization, int bonusEvents, DateTime? expires = null)
{
organization.BonusEventsPerMonth = bonusEvents;
organization.BonusExpiration = expires;
organization.GetCurrentUsage().Limit = organization.GetMaxEventsPerMonthWithBonus();
organization.GetCurrentUsage(_timeProvider).Limit = organization.GetMaxEventsPerMonthWithBonus(_timeProvider);
}
}
96 changes: 50 additions & 46 deletions src/Exceptionless.Core/Billing/StripeEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Exceptionless.Core.Models;
using Exceptionless.Core.Repositories;
using Foundatio.Repositories;
using Foundatio.Utility;
using Microsoft.Extensions.Logging;
using Stripe;

Expand All @@ -15,44 +14,47 @@ public class StripeEventHandler
private readonly IOrganizationRepository _organizationRepository;
private readonly IUserRepository _userRepository;
private readonly IMailer _mailer;
private readonly TimeProvider _timeProvider;

public StripeEventHandler(IOrganizationRepository organizationRepository, IUserRepository userRepository, IMailer mailer, ILogger<StripeEventHandler> logger)
public StripeEventHandler(IOrganizationRepository organizationRepository, IUserRepository userRepository, IMailer mailer,
TimeProvider timeProvider, ILogger<StripeEventHandler> logger)
{
_logger = logger;
_organizationRepository = organizationRepository;
_userRepository = userRepository;
_mailer = mailer;
_timeProvider = timeProvider;
}

public async Task HandleEventAsync(Stripe.Event stripeEvent)
{
switch (stripeEvent.Type)
{
case "customer.subscription.updated":
{
await SubscriptionUpdatedAsync((Subscription)stripeEvent.Data.Object);
break;
}
{
await SubscriptionUpdatedAsync((Subscription)stripeEvent.Data.Object);
break;
}
case "customer.subscription.deleted":
{
await SubscriptionDeletedAsync((Subscription)stripeEvent.Data.Object);
break;
}
{
await SubscriptionDeletedAsync((Subscription)stripeEvent.Data.Object);
break;
}
case "invoice.payment_succeeded":
{
await InvoicePaymentSucceededAsync((Invoice)stripeEvent.Data.Object);
break;
}
{
await InvoicePaymentSucceededAsync((Invoice)stripeEvent.Data.Object);
break;
}
case "invoice.payment_failed":
{
await InvoicePaymentFailedAsync((Invoice)stripeEvent.Data.Object);
break;
}
{
await InvoicePaymentFailedAsync((Invoice)stripeEvent.Data.Object);
break;
}
default:
{
_logger.LogTrace("Unhandled stripe webhook called. Type: {Type} Id: {Id} Account: {Account}", stripeEvent.Type, stripeEvent.Id, stripeEvent.Account);
break;
}
{
_logger.LogTrace("Unhandled stripe webhook called. Type: {Type} Id: {Id} Account: {Account}", stripeEvent.Type, stripeEvent.Id, stripeEvent.Account);
break;
}
}
}

Expand All @@ -71,41 +73,42 @@ private async Task SubscriptionUpdatedAsync(Subscription sub)
switch (sub.Status)
{
case "trialing":
{
status = BillingStatus.Trialing;
break;
}
{
status = BillingStatus.Trialing;
break;
}
case "active":
{
status = BillingStatus.Active;
break;
}
{
status = BillingStatus.Active;
break;
}
case "past_due":
{
status = BillingStatus.PastDue;
break;
}
{
status = BillingStatus.PastDue;
break;
}
case "canceled":
{
status = BillingStatus.Canceled;
break;
}
{
status = BillingStatus.Canceled;
break;
}
case "unpaid":
{
status = BillingStatus.Unpaid;
break;
}
{
status = BillingStatus.Unpaid;
break;
}
}

if (!status.HasValue || status.Value == org.BillingStatus)
return;

var utcNow = _timeProvider.GetUtcNow().UtcDateTime;
org.BillingStatus = status.Value;
org.BillingChangeDate = SystemClock.UtcNow;
org.BillingChangeDate = utcNow;
if (status.Value == BillingStatus.Unpaid || status.Value == BillingStatus.Canceled)
{
org.IsSuspended = true;
org.SuspensionDate = SystemClock.UtcNow;
org.SuspensionDate = utcNow;
org.SuspensionCode = SuspensionCode.Billing;
org.SuspensionNotes = $"Stripe subscription status changed to \"{status.Value}\".";
org.SuspendedByUserId = "Stripe";
Expand All @@ -129,14 +132,15 @@ private async Task SubscriptionDeletedAsync(Subscription sub)

_logger.LogInformation("Stripe subscription deleted. Customer: {CustomerId} Org: {Organization} Org Name: {OrganizationName}", sub.CustomerId, org.Id, org.Name);

var utcNow = _timeProvider.GetUtcNow().UtcDateTime;
org.BillingChangeDate = utcNow;
org.BillingStatus = BillingStatus.Canceled;
org.IsSuspended = true;
org.SuspensionDate = SystemClock.UtcNow;
org.SuspensionDate = utcNow;
org.SuspensionCode = SuspensionCode.Billing;
org.SuspensionNotes = "Stripe subscription deleted.";
org.SuspendedByUserId = "Stripe";

org.BillingChangeDate = SystemClock.UtcNow;
await _organizationRepository.SaveAsync(org, o => o.Cache().Originals());
}

Expand Down
28 changes: 15 additions & 13 deletions src/Exceptionless.Core/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public static void RegisterServices(IServiceCollection services, AppOptions appO
services.AddSingleton<ISerializer>(s => new JsonNetSerializer(s.GetRequiredService<JsonSerializerSettings>()));
services.AddSingleton<ITextSerializer>(s => new JsonNetSerializer(s.GetRequiredService<JsonSerializerSettings>()));

services.AddSingleton<ICacheClient>(s => new InMemoryCacheClient(new InMemoryCacheClientOptions { LoggerFactory = s.GetRequiredService<ILoggerFactory>(), CloneValues = true, Serializer = s.GetRequiredService<ISerializer>() }));
services.AddSingleton<ICacheClient>(s => new InMemoryCacheClient(new InMemoryCacheClientOptions { CloneValues = true, Serializer = s.GetRequiredService<ISerializer>(), TimeProvider = s.GetRequiredService<TimeProvider>(), LoggerFactory = s.GetRequiredService<ILoggerFactory>() }));

services.AddSingleton<ExceptionlessElasticConfiguration>();
services.AddSingleton<Nest.IElasticClient>(s => s.GetRequiredService<ExceptionlessElasticConfiguration>().Client);
Expand Down Expand Up @@ -112,13 +112,14 @@ public static void RegisterServices(IServiceCollection services, AppOptions appO
services.AddSingleton<IConnectionMapping, ConnectionMapping>();
services.AddSingleton<MessageService>();
services.AddStartupAction<MessageService>();
services.AddSingleton<IMessageBus>(s => new InMemoryMessageBus(new InMemoryMessageBusOptions { LoggerFactory = s.GetRequiredService<ILoggerFactory>(), Serializer = s.GetRequiredService<ISerializer>() }));
services.AddSingleton<IMessageBus>(s => new InMemoryMessageBus(new InMemoryMessageBusOptions { Serializer = s.GetRequiredService<ISerializer>(), TimeProvider = s.GetRequiredService<TimeProvider>(), LoggerFactory = s.GetRequiredService<ILoggerFactory>() }));
services.AddSingleton<IMessagePublisher>(s => s.GetRequiredService<IMessageBus>());
services.AddSingleton<IMessageSubscriber>(s => s.GetRequiredService<IMessageBus>());

services.AddSingleton<IFileStorage>(s => new InMemoryFileStorage(new InMemoryFileStorageOptions
{
Serializer = s.GetRequiredService<ITextSerializer>(),
TimeProvider = s.GetRequiredService<TimeProvider>(),
LoggerFactory = s.GetRequiredService<ILoggerFactory>()
}));

Expand Down Expand Up @@ -250,17 +251,17 @@ private static async Task CreateSampleDataAsync(IServiceProvider container)

public static void AddHostedJobs(IServiceCollection services, ILoggerFactory loggerFactory)
{
services.AddJob<CloseInactiveSessionsJob>(true);
services.AddJob<DailySummaryJob>(true);
services.AddJob<EventNotificationsJob>(true);
services.AddJob<EventPostsJob>(true);
services.AddJob<EventUserDescriptionsJob>(true);
services.AddJob<MailMessageJob>(true);
services.AddJob<StackStatusJob>(true);
services.AddJob<StackEventCountJob>(true);
services.AddJob<WebHooksJob>(true);
services.AddJob<WorkItemJob>(true);
services.AddJob<EventUsageJob>(true);
services.AddJob<CloseInactiveSessionsJob>(o => o.WaitForStartupActions(true));
services.AddJob<DailySummaryJob>(o => o.WaitForStartupActions(true));
services.AddJob<EventNotificationsJob>(o => o.WaitForStartupActions(true));
services.AddJob<EventPostsJob>(o => o.WaitForStartupActions(true));
services.AddJob<EventUserDescriptionsJob>(o => o.WaitForStartupActions(true));
services.AddJob<MailMessageJob>(o => o.WaitForStartupActions(true));
services.AddJob<StackStatusJob>(o => o.WaitForStartupActions(true));
services.AddJob<StackEventCountJob>(o => o.WaitForStartupActions(true));
services.AddJob<WebHooksJob>(o => o.WaitForStartupActions(true));
services.AddJob<WorkItemJob>(o => o.WaitForStartupActions(true));
services.AddJob<EventUsageJob>(o => o.WaitForStartupActions(true));

services.AddCronJob<CleanupDataJob>("30 */4 * * *");
services.AddCronJob<CleanupOrphanedDataJob>("45 */8 * * *");
Expand All @@ -286,6 +287,7 @@ private static IQueue<T> CreateQueue<T>(IServiceProvider container, TimeSpan? wo
{
WorkItemTimeout = workItemTimeout.GetValueOrDefault(TimeSpan.FromMinutes(5.0)),
Serializer = container.GetRequiredService<ISerializer>(),
TimeProvider = container.GetRequiredService<TimeProvider>(),
LoggerFactory = loggerFactory
});
}
Expand Down
Loading

0 comments on commit dacf97b

Please sign in to comment.