Browse Source

Revision for EventTimingChangeWorker/EventTimingChangeNotifier

pull/42/head
Berkan Sasmaz 5 years ago
parent
commit
0b14d76a26
  1. 19
      src/EventHub.BackgroundServices/Events/EventReminderNotifier.cs
  2. 2
      src/EventHub.BackgroundServices/Events/EventReminderWorker.cs
  3. 35
      src/EventHub.BackgroundServices/Events/EventTimingChangeNotifier.cs
  4. 26
      src/EventHub.BackgroundServices/Events/EventTimingChangeWorker.cs
  5. 26
      src/EventHub.BackgroundServices/Events/NewEventNotifier.cs
  6. 4
      src/EventHub.BackgroundServices/Events/NewEventWorker.cs
  7. 2
      src/EventHub.Domain/Events/Event.cs
  8. 32
      src/EventHub.Domain/Events/EventTimeChangeLocalEventHandler.cs
  9. 4
      src/EventHub.Domain/Events/Registrations/EventRegistration.cs
  10. 2638
      src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/20210614064205_Moved_IsTimingChangeEmailSent_To_Event.Designer.cs
  11. 35
      src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/20210614064205_Moved_IsTimingChangeEmailSent_To_Event.cs
  12. 13
      src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/EventHubMigrationsDbContextModelSnapshot.cs
  13. 5
      src/EventHub.EntityFrameworkCore/EntityFrameworkCore/EventHubDbContextModelCreatingExtensions.cs

19
src/EventHub.BackgroundServices/Events/EventReminderNotifier.cs

@ -21,10 +21,10 @@ namespace EventHub.Events
private readonly IAsyncQueryableExecuter _asyncExecuter;
public EventReminderNotifier(
IEmailSender emailSender,
ITemplateRenderer templateRenderer,
IRepository<AppUser, Guid> userRepository,
IRepository<EventRegistration, Guid> eventRegistrationRepository,
IEmailSender emailSender,
ITemplateRenderer templateRenderer,
IRepository<AppUser, Guid> userRepository,
IRepository<EventRegistration, Guid> eventRegistrationRepository,
IAsyncQueryableExecuter asyncExecuter)
{
_emailSender = emailSender;
@ -33,12 +33,17 @@ namespace EventHub.Events
_eventRegistrationRepository = eventRegistrationRepository;
_asyncExecuter = asyncExecuter;
}
public async Task NotifyAsync(Event @event)
{
if (@event is null)
{
return;
}
var userQueryable = await _userRepository.GetQueryableAsync();
var registrationQueryable = await _eventRegistrationRepository.GetQueryableAsync();
var userQuery = from eventRegistration in registrationQueryable
join user in userQueryable on eventRegistration.UserId equals user.Id
where eventRegistration.EventId == @event.Id
@ -61,7 +66,7 @@ namespace EventHub.Events
user.Email,
"The event has last thirty minutes to start!",
await _templateRenderer.RenderAsync(EmailTemplates.EventReminder, templateModel)
);
);
}
}
}

2
src/EventHub.BackgroundServices/Events/EventReminderWorker.cs

@ -45,7 +45,7 @@ namespace EventHub.Events
{
await eventReminderNotifier.NotifyAsync(@event);
}
@event.IsRemindingEmailSent = true;
await eventRepository.UpdateAsync(@event);
}

35
src/EventHub.BackgroundServices/Events/EventTimingChangeNotifier.cs

@ -16,22 +16,22 @@ namespace EventHub.Events
{
private readonly IEmailSender _emailSender;
private readonly ITemplateRenderer _templateRenderer;
private readonly IRepository<EventRegistration, Guid> _eventRegistrationRepository;
private readonly IAsyncQueryableExecuter _asyncExecuter;
private readonly IRepository<AppUser, Guid> _userRepository;
private readonly IRepository<EventRegistration, Guid> _eventRegistrationRepository;
public EventTimingChangeNotifier(
IEmailSender emailSender,
ITemplateRenderer templateRenderer,
IRepository<EventRegistration, Guid> eventRegistrationRepository,
IAsyncQueryableExecuter asyncExecuter,
IRepository<AppUser, Guid> userRepository)
IRepository<AppUser, Guid> userRepository,
IRepository<EventRegistration, Guid> eventRegistrationRepository)
{
_emailSender = emailSender;
_templateRenderer = templateRenderer;
_eventRegistrationRepository = eventRegistrationRepository;
_asyncExecuter = asyncExecuter;
_userRepository = userRepository;
_eventRegistrationRepository = eventRegistrationRepository;
}
public async Task NotifyAsync(Event @event)
@ -40,22 +40,19 @@ namespace EventHub.Events
{
return;
}
//TODO: It will be more performant if we join to users instead of individually query (already done for EventReminderNotifier)
var queryable = await _eventRegistrationRepository.GetQueryableAsync();
var registrations = await _asyncExecuter.ToListAsync(
queryable.Where(x => x.EventId == @event.Id && !x.IsTimingChangeEmailSent)
);
var userQueryable = await _userRepository.GetQueryableAsync();
var registrationQueryable = await _eventRegistrationRepository.GetQueryableAsync();
foreach (var registration in registrations)
{
var user = await _userRepository.FindAsync(registration.UserId);
if (user is null)
{
continue;
}
var userQuery = from eventRegistration in registrationQueryable
join user in userQueryable on eventRegistration.UserId equals user.Id
where eventRegistration.EventId == @event.Id
select user;
var users = await _asyncExecuter.ToListAsync(userQuery);
foreach (var user in users)
{
var templateModel = new
{
UserName = user.GetFullNameOrUsername(),
@ -70,11 +67,7 @@ namespace EventHub.Events
"Event time has been changed!",
await _templateRenderer.RenderAsync(EmailTemplates.EventTimingChanged, templateModel)
);
registration.IsTimingChangeEmailSent = true;
}
await _eventRegistrationRepository.UpdateManyAsync(registrations, autoSave: true);
}
}
}

26
src/EventHub.BackgroundServices/Events/EventTimingChangeWorker.cs

@ -1,7 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using EventHub.Events.Registrations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.BackgroundWorkers;
@ -17,7 +16,7 @@ namespace EventHub.Events
public EventTimingChangeWorker(
AbpAsyncTimer timer,
IServiceScopeFactory serviceScopeFactory
) : base(
) : base(
timer,
serviceScopeFactory)
{
@ -29,27 +28,26 @@ namespace EventHub.Events
{
var eventTimingChangeNotifier = workerContext.ServiceProvider.GetRequiredService<EventTimingChangeNotifier>();
var eventRepository = workerContext.ServiceProvider.GetRequiredService<IRepository<Event, Guid>>();
var eventRegistrationRepository = workerContext.ServiceProvider.GetRequiredService<IRepository<EventRegistration, Guid>>();
var asyncExecuter = workerContext.ServiceProvider.GetRequiredService<IAsyncQueryableExecuter>();
var queryable = await eventRegistrationRepository.GetQueryableAsync();
var query = queryable
.Where(x => !x.IsTimingChangeEmailSent)
.Select(x => x.EventId)
.Distinct();
var eventRegistrations = await asyncExecuter.ToListAsync(query);
foreach (var eventRegistration in eventRegistrations)
var queryable = await eventRepository.GetQueryableAsync();
var query = queryable.Where(x => !x.IsTimingChangeEmailSent);
var events = await asyncExecuter.ToListAsync(query);
foreach (var @event in events)
{
try
{
await eventTimingChangeNotifier.NotifyAsync(await eventRepository.FindAsync(eventRegistration));
await eventTimingChangeNotifier.NotifyAsync(@event);
@event.IsTimingChangeEmailSent = true;
await eventRepository.UpdateAsync(@event);
}
catch (Exception e)
{
Logger.LogError($"An error occurred while sending an email to the attendees of the event after the event time has changed. Error message: {e.Message}");
}
}
}
}
}

26
src/EventHub.BackgroundServices/Events/NewEventNotifier.cs

@ -36,21 +36,23 @@ namespace EventHub.Events
public async Task NotifyAsync(Event @event)
{
//TODO: It will be more performant if we join to users instead of individually query (already done for EventReminderNotifier)
if (@event is null)
{
return;
}
var userQueryable = await _userRepository.GetQueryableAsync();
var organizationMembershipQueryable = await _organizationMembershipsRepository.GetQueryableAsync();
var queryable = await _organizationMembershipsRepository.GetQueryableAsync();
var organizationMembers = await _asyncExecuter.ToListAsync(
queryable.Where(x => x.OrganizationId == @event.OrganizationId)
);
var userQuery = from organizationMembership in organizationMembershipQueryable
join user in userQueryable on organizationMembership.UserId equals user.Id
where organizationMembership.OrganizationId == @event.OrganizationId
select user;
foreach (var member in organizationMembers)
{
var user = await _userRepository.FindAsync(member.UserId);
if (user is null)
{
continue;
}
var users = await _asyncExecuter.ToListAsync(userQuery);
foreach (var user in users)
{
var templateModel = new
{
UserName = user.GetFullNameOrUsername(),

4
src/EventHub.BackgroundServices/Events/NewEventWorker.cs

@ -16,7 +16,7 @@ namespace EventHub.Events
{
public NewEventWorker(
AbpAsyncTimer timer,
IServiceScopeFactory serviceScopeFactory)
IServiceScopeFactory serviceScopeFactory)
: base(
timer,
serviceScopeFactory)
@ -46,7 +46,7 @@ namespace EventHub.Events
{
await newEventNotifier.NotifyAsync(@event);
}
@event.IsEmailSentToMembers = true;
await eventRepository.UpdateAsync(@event);
}

2
src/EventHub.Domain/Events/Event.cs

@ -40,6 +40,8 @@ namespace EventHub.Events
public int TimingChangeCount { get; set; }
public bool IsTimingChangeEmailSent { get; set; }
private Event()
{

32
src/EventHub.Domain/Events/EventTimeChangeLocalEventHandler.cs

@ -1,48 +1,30 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using EventHub.Events.Registrations;
using IdentityServer4.Validation;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EventBus;
using Volo.Abp.Linq;
namespace EventHub.Events
{
public class EventTimeChangeLocalEventHandler : ILocalEventHandler<EventTimeChangingEventData>, ITransientDependency
{
private readonly IRepository<EventRegistration, Guid> _eventRegistrationRepository;
private readonly IAsyncQueryableExecuter _asyncExecuter;
private readonly IRepository<Event, Guid> _eventRepository;
public EventTimeChangeLocalEventHandler(
IRepository<EventRegistration, Guid> eventRegistrationRepository,
IAsyncQueryableExecuter asyncExecuter)
public EventTimeChangeLocalEventHandler(IRepository<Event, Guid> eventRepository)
{
_eventRegistrationRepository = eventRegistrationRepository;
_asyncExecuter = asyncExecuter;
_eventRepository = eventRepository;
}
public async Task HandleEventAsync(EventTimeChangingEventData eventData)
{
await UpdateEventRegistrationForTimingChangeAsync(@eventData.Event);
await UpdateEventForTimingChangeAsync(eventData.Event);
}
private async Task UpdateEventRegistrationForTimingChangeAsync(Event @event)
private async Task UpdateEventForTimingChangeAsync(Event @event)
{
var eventRegistrationQueryable = await _eventRegistrationRepository.GetQueryableAsync();
var query = eventRegistrationQueryable.Where(x => x.EventId == @event.Id);
var eventRegistrations = await _asyncExecuter.ToListAsync(query);
@event.IsTimingChangeEmailSent = false;
foreach (var eventRegistration in eventRegistrations)
{
if (eventRegistration.IsTimingChangeEmailSent)
{
eventRegistration.IsTimingChangeEmailSent = false;
}
}
await _eventRegistrationRepository.UpdateManyAsync(eventRegistrations, true);
await _eventRepository.UpdateAsync(@event, true);
}
}
}

4
src/EventHub.Domain/Events/Registrations/EventRegistration.cs

@ -8,9 +8,7 @@ namespace EventHub.Events.Registrations
public Guid EventId { get; private set; }
public Guid UserId { get; private set; }
public bool IsTimingChangeEmailSent { get; set; }
private EventRegistration()
{

2638
src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/20210614064205_Moved_IsTimingChangeEmailSent_To_Event.Designer.cs

File diff suppressed because it is too large

35
src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/20210614064205_Moved_IsTimingChangeEmailSent_To_Event.cs

@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace EventHub.Migrations
{
public partial class Moved_IsTimingChangeEmailSent_To_Event : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsTimingChangeEmailSent",
table: "EhEventRegistrations");
migrationBuilder.AddColumn<bool>(
name: "IsTimingChangeEmailSent",
table: "EhEvents",
type: "boolean",
nullable: false,
defaultValue: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsTimingChangeEmailSent",
table: "EhEvents");
migrationBuilder.AddColumn<bool>(
name: "IsTimingChangeEmailSent",
table: "EhEventRegistrations",
type: "boolean",
nullable: false,
defaultValue: true);
}
}
}

13
src/EventHub.EntityFrameworkCore.DbMigrations/Migrations/EventHubMigrationsDbContextModelSnapshot.cs

@ -18,7 +18,7 @@ namespace EventHub.Migrations
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.PostgreSql)
.HasAnnotation("Relational:MaxIdentifierLength", 63)
.HasAnnotation("ProductVersion", "5.0.5")
.HasAnnotation("ProductVersion", "5.0.7")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
modelBuilder.Entity("EventHub.Countries.Country", b =>
@ -107,6 +107,11 @@ namespace EventHub.Migrations
b.Property<bool>("IsRemindingEmailSent")
.HasColumnType("boolean");
b.Property<bool>("IsTimingChangeEmailSent")
.ValueGeneratedOnAdd()
.HasColumnType("boolean")
.HasDefaultValue(true);
b.Property<string>("Language")
.HasMaxLength(16)
.HasColumnType("character varying(16)");
@ -191,12 +196,6 @@ namespace EventHub.Migrations
.HasColumnType("text")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsTimingChangeEmailSent")
.ValueGeneratedOnAdd()
.HasColumnType("boolean")
.HasDefaultValue(true)
.HasColumnName("IsTimingChangeEmailSent");
b.Property<Guid>("UserId")
.HasColumnType("uuid");

5
src/EventHub.EntityFrameworkCore/EntityFrameworkCore/EventHubDbContextModelCreatingExtensions.cs

@ -73,6 +73,8 @@ namespace EventHub.EntityFrameworkCore
b.HasOne<Country>().WithMany().HasForeignKey(x => x.CountryId).OnDelete(DeleteBehavior.NoAction);
b.Property(x => x.IsTimingChangeEmailSent).HasDefaultValue(true);
b.HasIndex(x => new {x.OrganizationId, x.StartTime});
b.HasIndex(x => x.StartTime);
b.HasIndex(x => x.UrlCode);
@ -86,9 +88,6 @@ namespace EventHub.EntityFrameworkCore
b.ConfigureByConvention();
b.Property(x => x.IsTimingChangeEmailSent).HasDefaultValue(true)
.HasColumnName(nameof(EventRegistration.IsTimingChangeEmailSent));
b.HasOne<Event>().WithMany().HasForeignKey(x => x.EventId).IsRequired().OnDelete(DeleteBehavior.NoAction);
if (isMigrationDbContext)

Loading…
Cancel
Save