Skip to content

Commit

Permalink
optimized queries for periodic job
Browse files Browse the repository at this point in the history
1. Added indexes for needed columns
2. Used bulk update and bulk insert
  • Loading branch information
AndriyBorkovich committed May 2, 2024
1 parent 724fb06 commit f19f4f1
Show file tree
Hide file tree
Showing 11 changed files with 911 additions and 15 deletions.
4 changes: 3 additions & 1 deletion src/BSMS.API/BackgroundJobs/ScheduleTripsJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ private async Task GenerateTrips()
var currentDateTime = DateTime.Now;
var currentDayOfWeek = currentDateTime.DayOfWeek;

var isTripsScheduled = await dbContext.Trips.AnyAsync(t => t.DepartureTime.Value.Date == currentDateTime.Date);
var isTripsScheduled = await dbContext.Trips
.AnyAsync(t => t.DepartureTime != null && t.DepartureTime.Value.Date == currentDateTime.Date);

if (!isTripsScheduled)
{
// Query for bus schedule entries for the current day of the week
Expand Down
33 changes: 27 additions & 6 deletions src/BSMS.API/BackgroundJobs/TripStartOrStopPeriodicJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ namespace BSMS.API.BackgroundJobs;
/// Periodic job that handles start or stop of trips based on current time
/// </summary>
/// <param name="serviceProvider"></param>
/// <param name="logger"></param>
public class TripStartOrStopPeriodicJob(
IServiceProvider serviceProvider) : BackgroundService
IServiceProvider serviceProvider,
ILogger<TripStartOrStopPeriodicJob> logger) : BackgroundService
{
/// <inheritdoc/>
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
Expand All @@ -29,13 +31,14 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)

// Query for bus schedule entries where departure time has arrived
var tripsToStart = await dbContext.Trips
.Where(t => t.Status != TripStatus.Canceled
.Where(t => t.Status != TripStatus.Canceled && t.Status != TripStatus.Delayed
&& t.BusScheduleEntry != null
&& t.BusScheduleEntry.Day == currentDay
&& t.BusScheduleEntry.DepartureTime.Minute == currentMinute
&& t.BusScheduleEntry.DepartureTime.Hour == currentHour)
.ToListAsync(cancellationToken: stoppingToken);

var tripsToSetInTransit = new List<Trip>();
foreach (var trip in tripsToStart)
{
if (trip is not null)
Expand All @@ -50,12 +53,18 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
trip.Status = TripStatus.Delayed;
}

dbContext.Trips.Update(trip);
tripsToSetInTransit.Add(trip);
}
}

if (tripsToSetInTransit.Count is not 0)
{
await dbContext.BulkUpdateAsync(tripsToSetInTransit);
logger.LogInformation("Some trips has started");
}

// Query for bus schedule entries where arival time has come
await dbContext.Trips
var updatedRows = await dbContext.Trips
.Where(t => t.Status == TripStatus.InTransit
&& t.BusScheduleEntry != null
&& t.BusScheduleEntry.Day == currentDay
Expand All @@ -65,24 +74,36 @@ await dbContext.Trips
t => t.SetProperty(e => e.Status, TripStatus.Completed)
.SetProperty(e => e.ArrivalTime, DateTime.Now),
cancellationToken: stoppingToken);

if(updatedRows > 0)
{
logger.LogInformation("Some trips has completed");
}

// Double check delayed trips, try to start them

var delayedTrips = await dbContext.Trips
.Where(t => t.Status == TripStatus.Delayed
&& t.DepartureTime.Value.Date == currentTime.Date)
&& t.DepartureTime != null
&& t.DepartureTime.Value.Date == currentTime.Date)
.ToListAsync(cancellationToken: stoppingToken);

var tripsToRestart = new List<Trip>();
foreach (var trip in delayedTrips)
{
if (await CanStart(dbContext, trip))
{
// Update trip status to "Scheduled" and set departure time to current time
trip.Status = TripStatus.Scheduled;
trip.DepartureTime = currentTime;
tripsToRestart.Add(trip);
}
}

if (tripsToRestart.Count is not 0)
{
await dbContext.BulkUpdateAsync(tripsToRestart);
}

await dbContext.SaveChangesAsync(stoppingToken);
}

Expand Down
2 changes: 1 addition & 1 deletion src/BSMS.API/Controllers/TicketController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace BSMS.API.Controllers;
/// <inheritdoc />
[ApiController]
[Route("api/[controller]")]
[Authorization(Role.Admin)]
[Authorization(Role.Admin, Role.Passenger)]
public class TicketController(ISender sender) : ControllerBase
{
/// <summary>
Expand Down
3 changes: 2 additions & 1 deletion src/BSMS.API/Controllers/TripController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using BSMS.API.Filters;
using BSMS.Application.Features.Common;
using BSMS.Application.Features.Trip.Queries.GetAll;
using BSMS.Core.Enums;
using MediatR;
using Microsoft.AspNetCore.Mvc;

Expand All @@ -9,7 +10,7 @@ namespace BSMS.API.Controllers;
/// <inheritdoc/>
[ApiController]
[Route("/api/[controller]")]
[Authorization]
[Authorization(Role.Admin, Role.Driver, Role.Passenger)]
public class TripController(ISender sender) : ControllerBase
{
/// <summary>
Expand Down
6 changes: 3 additions & 3 deletions src/BSMS.API/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@
.AddCustomIdentityServices();

builder.Services.AddHostedService<CacheCleaningJob>();
builder.Services.AddHostedService<DatabaseSeedJob>(); // comment if you have already filled DB
// builder.Services.AddHostedService<ScheduleTripsJob>();
// builder.Services.AddHostedService<TripStartOrStopPeriodicJob>();
//builder.Services.AddHostedService<DatabaseSeedJob>(); // comment if you have already filled DB
builder.Services.AddHostedService<ScheduleTripsJob>();
builder.Services.AddHostedService<TripStartOrStopPeriodicJob>();

builder.Services.AddCors(options =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public async Task<MethodResult<CreatedEntityResponse>> Handle(
}

var ticket = mapper.Map<Core.Entities.Ticket>(request);
// 'Active' ticket status creation is handled by sql trigger
await repository.InsertAsync(ticket);

result.Data = new CreatedEntityResponse(ticket.TicketId);
Expand Down
2 changes: 2 additions & 0 deletions src/BSMS.Core/Entities/BusScheduleEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace BSMS.Core.Entities;

[Index(nameof(Day))]
[Index(nameof(DepartureTime))]
[Index(nameof(ArrivalTime))]
public class BusScheduleEntry
{
[Key]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ create or alter view TripView
WITH SCHEMABINDING AS
select
t.TripId,
bse.DepartureTime,
bse.ArrivalTime,
t.DepartureTime,
t.ArrivalTime,
r.Origin + ' - ' + r.Destination as RouteName,
b.Brand as BusBrand,
b.CompanyName,
Expand Down
Loading

0 comments on commit f19f4f1

Please sign in to comment.