refactor(database,worker): add paginated findAllBy and migrate jobs to batch fetching

- Add FindAllBy type and implement DatabaseService.findAllBy with batchSize/limit/skip support.
- Add normalizePositiveNumber helper used by findAllBy.
- Add ProjectService.getAllActiveProjects convenience wrapper that uses findAllBy.
- Replace many worker cron jobs' findBy calls with findAllBy, introduce per-job batch size constants, remove LIMIT_MAX imports, and pass batchSize/skip instead of one large limit.
- Convert long-running deletes/hard-deletes to paginated loops (repeat until no more records deleted).
- Adjust various query usages to use LIMIT_PER_PROJECT where appropriate as batchSize.
This commit is contained in:
Nawaz Dhandala
2025-10-28 14:32:45 +00:00
parent 60c472cc09
commit bb09dafbcc
54 changed files with 374 additions and 300 deletions

View File

@@ -2,6 +2,7 @@ import { EncryptionSecret, WorkflowHostname } from "../EnvironmentConfig";
import PostgresAppInstance from "../Infrastructure/PostgresDatabase";
import ClusterKeyAuthorization from "../Middleware/ClusterKeyAuthorization";
import CountBy from "../Types/Database/CountBy";
import FindAllBy from "../Types/Database/FindAllBy";
import CreateBy from "../Types/Database/CreateBy";
import DeleteBy from "../Types/Database/DeleteBy";
import DeleteById from "../Types/Database/DeleteById";
@@ -1168,6 +1169,82 @@ class DatabaseService<TBaseModel extends BaseModel> extends BaseService {
}
}
@CaptureSpan()
public async findAllBy(
findAllBy: FindAllBy<TBaseModel>,
): Promise<Array<TBaseModel>> {
const { batchSize, limit, skip, ...rest } = findAllBy;
const batchSizeValue: number =
this.normalizePositiveNumber(batchSize) || LIMIT_MAX;
let remaining: number | undefined = this.normalizePositiveNumber(limit);
let currentSkip: number = this.normalizePositiveNumber(skip) || 0;
if (batchSizeValue <= 0) {
throw new BadDataException("batchSize must be greater than 0");
}
const results: Array<TBaseModel> = [];
while (true) {
const currentBatchSize: number =
remaining !== undefined
? Math.min(batchSizeValue, Math.max(remaining, 0))
: batchSizeValue;
if (currentBatchSize <= 0) {
break;
}
const page: Array<TBaseModel> = await this.findBy({
...rest,
skip: currentSkip,
limit: currentBatchSize,
});
if (page.length === 0) {
break;
}
results.push(...page);
currentSkip += page.length;
if (remaining !== undefined) {
remaining -= page.length;
if (remaining <= 0) {
break;
}
}
if (page.length < currentBatchSize) {
break;
}
}
return results;
}
private normalizePositiveNumber(
value?: PositiveNumber | number,
): number | undefined {
if (value === undefined || value === null) {
return undefined;
}
if (value instanceof PositiveNumber) {
return value.toNumber();
}
if (typeof value === "number") {
return value;
}
return undefined;
}
@CaptureSpan()
public async findBy(findBy: FindBy<TBaseModel>): Promise<Array<TBaseModel>> {
return await this._findBy(findBy);

View File

@@ -71,6 +71,8 @@ import URL from "../../Types/API/URL";
import Exception from "../../Types/Exception/Exception";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
import DatabaseConfig from "../DatabaseConfig";
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
import PositiveNumber from "../../Types/PositiveNumber";
export interface CurrentPlan {
plan: PlanType | null;
@@ -1435,6 +1437,29 @@ export class ProjectService extends DatabaseService<Model> {
};
}
@CaptureSpan()
public async getAllActiveProjects(params?: {
select?: Select<Model>;
props?: DatabaseCommonInteractionProps;
batchSize?: PositiveNumber | number;
skip?: PositiveNumber | number;
limit?: PositiveNumber | number;
}): Promise<Array<Model>> {
const select: Select<Model> | undefined =
params?.select || ({ _id: true } as Select<Model>);
const props: DatabaseCommonInteractionProps =
params?.props || { isRoot: true };
return await this.findAllBy({
query: this.getActiveProjectStatusQuery(),
select,
props,
batchSize: params?.batchSize,
skip: params?.skip,
limit: params?.limit,
});
}
@CaptureSpan()
public async getProjectLinkInDashboard(projectId: ObjectID): Promise<URL> {
const dashboardUrl: URL = await DatabaseConfig.getDashboardUrl();

View File

@@ -0,0 +1,29 @@
import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
import GroupBy from "./GroupBy";
import Query from "./Query";
import Select from "./Select";
import Sort from "./Sort";
import PositiveNumber from "../../../Types/PositiveNumber";
export default interface FindAllBy<TBaseModel extends BaseModel> {
query: Query<TBaseModel>;
select?: Select<TBaseModel> | undefined;
sort?: Sort<TBaseModel> | undefined;
groupBy?: GroupBy<TBaseModel> | undefined;
props: DatabaseCommonInteractionProps;
/**
* Optional number of documents to skip before fetching results.
* Acts the same way as `skip` in `findBy` but defaults to 0 when omitted.
*/
skip?: PositiveNumber | number | undefined;
/**
* Optional total number of documents to return across all batches.
* When omitted, the method keeps fetching until no more data is returned.
*/
limit?: PositiveNumber | number | undefined;
/**
* Size of each batch fetched from the database. Defaults to LIMIT_MAX when not provided.
*/
batchSize?: PositiveNumber | number | undefined;
}

View File

@@ -2,7 +2,6 @@ import { EVERY_DAY } from "Common/Utils/CronTime";
import RunCron from "../../Utils/Cron";
import logger from "Common/Server/Utils/Logger";
import ProjectService from "Common/Server/Services/ProjectService";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import AlertService from "Common/Server/Services/AlertService";
import Project from "Common/Models/DatabaseModels/Project";
import Alert from "Common/Models/DatabaseModels/Alert";
@@ -13,19 +12,12 @@ RunCron(
async () => {
try {
// get all projects, then get all alerts for each project, then refresh the current state of each alert.
const projects: Array<Project> = await ProjectService.findBy({
query: {
...ProjectService.getActiveProjectStatusQuery(),
},
select: {
_id: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
});
const projects: Array<Project> =
await ProjectService.getAllActiveProjects({
select: {
_id: true,
},
});
for (const project of projects) {
try {
@@ -33,15 +25,13 @@ RunCron(
continue;
}
const alerts: Array<Alert> = await AlertService.findBy({
const alerts: Array<Alert> = await AlertService.findAllBy({
query: {
projectId: project.id,
},
select: {
_id: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
@@ -27,19 +26,20 @@ import ObjectID from "Common/Types/ObjectID";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const ALERT_OWNER_BATCH_SIZE: number = 100;
RunCron(
"AlertOwner:SendCreatedResourceEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
// get all scheduled events of all the projects.
const alerts: Array<Alert> = await AlertService.findBy({
const alerts: Array<Alert> = await AlertService.findAllBy({
query: {
isOwnerNotifiedOfAlertCreation: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -69,6 +69,7 @@ RunCron(
},
alertNumber: true,
},
batchSize: ALERT_OWNER_BATCH_SIZE,
});
for (const alert of alerts) {

View File

@@ -1,7 +1,6 @@
import RunCron from "../../Utils/Cron";
import BaseModel from "Common/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -25,19 +24,20 @@ import { AlertFeedEventType } from "Common/Models/DatabaseModels/AlertFeed";
import { Blue500 } from "Common/Types/BrandColors";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const ALERT_NOTE_BATCH_SIZE: number = 100;
RunCron(
"AlertOwner:SendsNotePostedEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const privateNotes: Array<AlertInternalNote> =
await AlertInternalNoteService.findBy({
await AlertInternalNoteService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -45,6 +45,7 @@ RunCron(
alertId: true,
projectId: true,
},
batchSize: ALERT_NOTE_BATCH_SIZE,
});
const privateNoteIds: Array<string> = privateNotes.map(

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -23,25 +22,27 @@ import AlertOwnerUser from "Common/Models/DatabaseModels/AlertOwnerUser";
import User from "Common/Models/DatabaseModels/User";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const ALERT_OWNER_BATCH_SIZE: number = 100;
RunCron(
"AlertOwner:SendOwnerAddedEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const alertOwnerTeams: Array<AlertOwnerTeam> =
await AlertOwnerTeamService.findBy({
await AlertOwnerTeamService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
alertId: true,
teamId: true,
},
batchSize: ALERT_OWNER_BATCH_SIZE,
});
const alertOwnersMap: Dictionary<Array<User>> = {};
@@ -75,14 +76,13 @@ RunCron(
}
const alertOwnerUsers: Array<AlertOwnerUser> =
await AlertOwnerUserService.findBy({
await AlertOwnerUserService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -93,6 +93,7 @@ RunCron(
name: true,
},
},
batchSize: ALERT_OWNER_BATCH_SIZE,
});
for (const alertOwnerUser of alertOwnerUsers) {

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
@@ -28,6 +27,8 @@ import UserService from "Common/Server/Services/UserService";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const ALERT_STATE_BATCH_SIZE: number = 100;
RunCron(
"AlertOwner:SendStateChangeEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
@@ -35,14 +36,13 @@ RunCron(
// get all scheduled events of all the projects.
const alertStateTimelines: Array<AlertStateTimeline> =
await AlertStateTimelineService.findBy({
await AlertStateTimelineService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -56,6 +56,7 @@ RunCron(
name: true,
},
},
batchSize: ALERT_STATE_BATCH_SIZE,
});
for (const alertStateTimeline of alertStateTimelines) {

View File

@@ -3,7 +3,6 @@ import { FileRoute } from "Common/ServiceRoute";
import Hostname from "Common/Types/API/Hostname";
import Protocol from "Common/Types/API/Protocol";
import URL from "Common/Types/API/URL";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
import SMS from "Common/Types/SMS/SMS";
@@ -33,13 +32,15 @@ import StatusPageSubscriberNotificationStatus from "Common/Types/StatusPage/Stat
import SlackUtil from "Common/Server/Utils/Workspace/Slack/Slack";
import MicrosoftTeamsUtil from "Common/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams";
const ANNOUNCEMENT_BATCH_SIZE: number = 100;
RunCron(
"Announcement:SendNotificationToSubscribers",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
// First, mark announcements as Skipped if they should not be notified
const announcementsToSkip: Array<StatusPageAnnouncement> =
await StatusPageAnnouncementService.findBy({
await StatusPageAnnouncementService.findAllBy({
query: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Pending,
@@ -51,11 +52,11 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
},
batchSize: ANNOUNCEMENT_BATCH_SIZE,
});
logger.debug(
@@ -84,7 +85,7 @@ RunCron(
// get all scheduled events of all the projects.
const announcements: Array<StatusPageAnnouncement> =
await StatusPageAnnouncementService.findBy({
await StatusPageAnnouncementService.findAllBy({
query: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Pending,
@@ -96,7 +97,6 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -110,6 +110,7 @@ RunCron(
},
showAnnouncementAt: true,
},
batchSize: ANNOUNCEMENT_BATCH_SIZE,
});
logger.debug(
@@ -213,7 +214,7 @@ RunCron(
`Announcement ${announcement.id} has ${announcement.monitors.length} monitor(s) specified. Filtering subscribers by affected resources.`,
);
statusPageResources = await StatusPageResourceService.findBy({
statusPageResources = await StatusPageResourceService.findAllBy({
query: {
statusPageId: statuspage.id!,
monitorId: QueryHelper.any(
@@ -230,13 +231,13 @@ RunCron(
isRoot: true,
ignoreHooks: true,
},
skip: 0,
limit: LIMIT_MAX,
select: {
_id: true,
displayName: true,
statusPageId: true,
},
skip: 0,
batchSize: ANNOUNCEMENT_BATCH_SIZE,
});
logger.debug(

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import { EVERY_THIRTY_MINUTES } from "Common/Utils/CronTime";
import OneUptimeDate from "Common/Types/Date";
import CopilotAction from "Common/Models/DatabaseModels/CopilotAction";
@@ -7,6 +6,8 @@ import CopilotActionService from "Common/Server/Services/CopilotActionService";
import CopilotActionStatus from "Common/Types/Copilot/CopilotActionStatus";
import QueryHelper from "Common/Server/Types/Database/QueryHelper";
const COPILOT_ACTION_BATCH_SIZE: number = 100;
RunCron(
"CopilotAction:MoveThemBackToQueueIfProcessingForLongtime",
{ schedule: EVERY_THIRTY_MINUTES, runOnStartup: false },
@@ -19,7 +20,7 @@ RunCron(
//get stalled copilot actions and move them back to queue so they can be processed again.
const stalledActions: Array<CopilotAction> =
await CopilotActionService.findBy({
await CopilotActionService.findAllBy({
query: {
copilotActionStatus: CopilotActionStatus.PROCESSING,
statusChangedAt: QueryHelper.lessThanEqualToOrNull(lastHour),
@@ -27,11 +28,11 @@ RunCron(
select: {
_id: true,
},
limit: LIMIT_MAX,
skip: 0,
props: {
isRoot: true,
},
batchSize: COPILOT_ACTION_BATCH_SIZE,
});
for (const stalledAction of stalledActions) {

View File

@@ -31,16 +31,22 @@ RunCron(
try {
// Retain data for 30 days for accidental deletion, and then hard delete.
await service.hardDeleteBy({
query: {
deletedAt: QueryHelper.lessThan(OneUptimeDate.getSomeDaysAgo(30)),
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
});
let deletedCount: number = 0;
do {
deletedCount = await service.hardDeleteBy({
query: {
deletedAt: QueryHelper.lessThan(
OneUptimeDate.getSomeDaysAgo(30),
),
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
});
} while (deletedCount > 0);
} catch (err) {
logger.error(err);
}
@@ -64,20 +70,24 @@ RunCron(
try {
// Retain data for 30 days for accidental deletion, and then hard delete.
await service.hardDeleteBy({
query: {
[service.hardDeleteItemByColumnName]: QueryHelper.lessThan(
OneUptimeDate.getSomeDaysAgo(
service.hardDeleteItemsOlderThanDays,
let deletedCount: number = 0;
do {
deletedCount = await service.hardDeleteBy({
query: {
[service.hardDeleteItemByColumnName]: QueryHelper.lessThan(
OneUptimeDate.getSomeDaysAgo(
service.hardDeleteItemsOlderThanDays,
),
),
),
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
});
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
});
} while (deletedCount > 0);
} catch (err) {
logger.error(err);
}

View File

@@ -2,29 +2,25 @@ import { EVERY_DAY } from "Common/Utils/CronTime";
import RunCron from "../../Utils/Cron";
import logger from "Common/Server/Utils/Logger";
import ProjectService from "Common/Server/Services/ProjectService";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import IncidentService from "Common/Server/Services/IncidentService";
import Project from "Common/Models/DatabaseModels/Project";
import Incident from "Common/Models/DatabaseModels/Incident";
const INCIDENT_PROJECT_BATCH_SIZE: number = 100;
const INCIDENT_BATCH_SIZE: number = 100;
RunCron(
"Incident:KeepCurrentStateConsistent",
{ schedule: EVERY_DAY, runOnStartup: true },
async () => {
try {
// get all projects, then get all incidents for each project, then refresh the current state of each incident.
const projects: Array<Project> = await ProjectService.findBy({
query: {
...ProjectService.getActiveProjectStatusQuery(),
},
const projects: Array<Project> = await ProjectService.getAllActiveProjects({
select: {
_id: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
batchSize: INCIDENT_PROJECT_BATCH_SIZE,
});
for (const project of projects) {
@@ -33,7 +29,7 @@ RunCron(
continue;
}
const incidents: Array<Incident> = await IncidentService.findBy({
const incidents: Array<Incident> = await IncidentService.findAllBy({
query: {
projectId: project.id,
},
@@ -41,10 +37,10 @@ RunCron(
_id: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
batchSize: INCIDENT_BATCH_SIZE,
});
for (const incident of incidents) {

View File

@@ -3,7 +3,7 @@ import { FileRoute } from "Common/ServiceRoute";
import Hostname from "Common/Types/API/Hostname";
import Protocol from "Common/Types/API/Protocol";
import URL from "Common/Types/API/URL";
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
import ObjectID from "Common/Types/ObjectID";
@@ -36,12 +36,14 @@ import { Blue500 } from "Common/Types/BrandColors";
import SlackUtil from "Common/Server/Utils/Workspace/Slack/Slack";
import MicrosoftTeamsUtil from "Common/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams";
const INCIDENT_SUBSCRIBER_BATCH_SIZE: number = 100;
RunCron(
"Incident:SendNotificationToSubscribers",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
// First, mark incidents as Skipped if they should not be notified
const incidentsToSkip: Array<Incident> = await IncidentService.findBy({
const incidentsToSkip: Array<Incident> = await IncidentService.findAllBy({
query: {
subscriberNotificationStatusOnIncidentCreated:
StatusPageSubscriberNotificationStatus.Pending,
@@ -50,11 +52,11 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
},
batchSize: INCIDENT_SUBSCRIBER_BATCH_SIZE,
});
logger.debug(
@@ -84,7 +86,7 @@ RunCron(
}
// get all scheduled events of all the projects.
const incidents: Array<Incident> = await IncidentService.findBy({
const incidents: Array<Incident> = await IncidentService.findAllBy({
query: {
subscriberNotificationStatusOnIncidentCreated:
StatusPageSubscriberNotificationStatus.Pending,
@@ -93,7 +95,6 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -109,6 +110,7 @@ RunCron(
},
incidentNumber: true,
},
batchSize: INCIDENT_SUBSCRIBER_BATCH_SIZE,
});
logger.debug(
@@ -180,7 +182,7 @@ RunCron(
// get status page resources from monitors.
const statusPageResources: Array<StatusPageResource> =
await StatusPageResourceService.findBy({
await StatusPageResourceService.findAllBy({
query: {
monitorId: QueryHelper.any(
incident.monitors
@@ -197,12 +199,12 @@ RunCron(
ignoreHooks: true,
},
skip: 0,
limit: LIMIT_PER_PROJECT,
select: {
_id: true,
displayName: true,
statusPageId: true,
},
batchSize: LIMIT_PER_PROJECT,
});
logger.debug(

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
@@ -28,19 +27,20 @@ import { Yellow500 } from "Common/Types/BrandColors";
import ObjectID from "Common/Types/ObjectID";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const INCIDENT_OWNER_BATCH_SIZE: number = 100;
RunCron(
"IncidentOwner:SendCreatedResourceEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
// get all scheduled events of all the projects.
const incidents: Array<Incident> = await IncidentService.findBy({
const incidents: Array<Incident> = await IncidentService.findAllBy({
query: {
isOwnerNotifiedOfResourceCreation: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -70,6 +70,7 @@ RunCron(
},
incidentNumber: true,
},
batchSize: INCIDENT_OWNER_BATCH_SIZE,
});
for (const incident of incidents) {

View File

@@ -1,7 +1,6 @@
import RunCron from "../../Utils/Cron";
import BaseModel from "Common/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -28,19 +27,20 @@ import { Blue500 } from "Common/Types/BrandColors";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const INCIDENT_NOTE_BATCH_SIZE: number = 100;
RunCron(
"IncidentOwner:SendsNotePostedEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const publicNotes: Array<IncidentPublicNote> =
await IncidentPublicNoteService.findBy({
await IncidentPublicNoteService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -48,17 +48,17 @@ RunCron(
incidentId: true,
projectId: true,
},
batchSize: INCIDENT_NOTE_BATCH_SIZE,
});
const privateNotes: Array<IncidentInternalNote> =
await IncidentInternalNoteService.findBy({
await IncidentInternalNoteService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -66,6 +66,7 @@ RunCron(
incidentId: true,
projectId: true,
},
batchSize: INCIDENT_NOTE_BATCH_SIZE,
});
const privateNoteIds: Array<string> = privateNotes.map(

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -24,25 +23,27 @@ import Monitor from "Common/Models/DatabaseModels/Monitor";
import User from "Common/Models/DatabaseModels/User";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const INCIDENT_OWNER_BATCH_SIZE: number = 100;
RunCron(
"IncidentOwner:SendOwnerAddedEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const incidentOwnerTeams: Array<IncidentOwnerTeam> =
await IncidentOwnerTeamService.findBy({
await IncidentOwnerTeamService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
incidentId: true,
teamId: true,
},
batchSize: INCIDENT_OWNER_BATCH_SIZE,
});
const incidentOwnersMap: Dictionary<Array<User>> = {};
@@ -76,14 +77,13 @@ RunCron(
}
const incidentOwnerUsers: Array<IncidentOwnerUser> =
await IncidentOwnerUserService.findBy({
await IncidentOwnerUserService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -94,6 +94,7 @@ RunCron(
name: true,
},
},
batchSize: INCIDENT_OWNER_BATCH_SIZE,
});
for (const incidentOwnerUser of incidentOwnerUsers) {

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
@@ -28,6 +27,8 @@ import UserService from "Common/Server/Services/UserService";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const INCIDENT_STATE_BATCH_SIZE: number = 100;
RunCron(
"IncidentOwner:SendStateChangeEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
@@ -35,14 +36,13 @@ RunCron(
// get all scheduled events of all the projects.
const incidentStateTimelines: Array<IncidentStateTimeline> =
await IncidentStateTimelineService.findBy({
await IncidentStateTimelineService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -57,6 +57,7 @@ RunCron(
isResolvedState: true,
},
},
batchSize: INCIDENT_STATE_BATCH_SIZE,
});
for (const incidentStateTimeline of incidentStateTimelines) {

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import { CheckOn } from "Common/Types/Monitor/CriteriaFilter";
import IncomingMonitorRequest from "Common/Types/Monitor/IncomingMonitor/IncomingMonitorRequest";
import MonitorType from "Common/Types/Monitor/MonitorType";
@@ -25,7 +24,7 @@ RunCron(
);
const newIncomingRequestMonitors: Array<Monitor> =
await MonitorService.findBy({
await MonitorService.findAllBy({
query: {
...MonitorService.getEnabledMonitorQuery(),
monitorType: MonitorType.IncomingRequest,
@@ -48,11 +47,9 @@ RunCron(
sort: {
createdAt: SortOrder.Ascending,
},
limit: LIMIT_MAX,
skip: 0,
});
const incomingRequestMonitors: Array<Monitor> = await MonitorService.findBy(
const incomingRequestMonitors: Array<Monitor> = await MonitorService.findAllBy(
{
query: {
...MonitorService.getEnabledMonitorQuery(),
@@ -76,8 +73,6 @@ RunCron(
sort: {
incomingRequestMonitorHeartbeatCheckedAt: SortOrder.Ascending,
},
limit: LIMIT_MAX,
skip: 0,
},
);

View File

@@ -1,6 +1,5 @@
import { PlanType } from "Common/Types/Billing/SubscriptionPlan";
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Sleep from "Common/Types/Sleep";
import { EVERY_DAY, EVERY_FIVE_MINUTE } from "Common/Utils/CronTime";
import {
@@ -31,13 +30,11 @@ RunCron(
return;
}
const projects: Array<Project> = await ProjectService.findBy({
const projects: Array<Project> = await ProjectService.findAllBy({
query: {},
select: {
_id: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},

View File

@@ -2,7 +2,6 @@ import { EVERY_DAY } from "Common/Utils/CronTime";
import RunCron from "../../Utils/Cron";
import logger from "Common/Server/Utils/Logger";
import ProjectService from "Common/Server/Services/ProjectService";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import MonitorService from "Common/Server/Services/MonitorService";
import Project from "Common/Models/DatabaseModels/Project";
import Monitor from "Common/Models/DatabaseModels/Monitor";
@@ -17,19 +16,12 @@ RunCron(
* if they are different, then update the current status of the monitor.
*/
const projects: Array<Project> = await ProjectService.findBy({
query: {
...ProjectService.getActiveProjectStatusQuery(),
},
select: {
_id: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
});
const projects: Array<Project> =
await ProjectService.getAllActiveProjects({
select: {
_id: true,
},
});
for (const project of projects) {
try {
@@ -41,15 +33,13 @@ RunCron(
continue;
}
const monitors: Array<Monitor> = await MonitorService.findBy({
const monitors: Array<Monitor> = await MonitorService.findAllBy({
query: {
projectId: project.id,
},
select: {
_id: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -23,15 +22,13 @@ RunCron(
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
// get all scheduled events of all the projects.
const monitors: Array<Monitor> = await MonitorService.findBy({
const monitors: Array<Monitor> = await MonitorService.findAllBy({
query: {
isOwnerNotifiedOfResourceCreation: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
name: true,

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -28,15 +27,13 @@ RunCron(
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const monitorOwnerTeams: Array<MonitorOwnerTeam> =
await MonitorOwnerTeamService.findBy({
await MonitorOwnerTeamService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
monitorId: true,
@@ -75,15 +72,13 @@ RunCron(
}
const monitorOwnerUsers: Array<MonitorOwnerUser> =
await MonitorOwnerUserService.findBy({
await MonitorOwnerUserService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
monitorId: true,

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
@@ -29,15 +28,13 @@ RunCron(
// get all scheduled events of all the projects.
const monitorStatusTimelines: Array<MonitorStatusTimeline> =
await MonitorStatusTimelineService.findBy({
await MonitorStatusTimelineService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
projectId: true,

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import OnCallDutyPolicyStatus from "Common/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
@@ -21,7 +20,7 @@ RunCron(
// get all pending on-call executions and execute them all at once.
const pendingExecutions: Array<OnCallDutyPolicyExecutionLog> =
await OnCallDutyPolicyExecutionLogService.findBy({
await OnCallDutyPolicyExecutionLogService.findAllBy({
query: {
status: OnCallDutyPolicyStatus.Executing,
},
@@ -42,8 +41,6 @@ RunCron(
},
onCallPolicyExecutionRepeatCount: true,
},
limit: LIMIT_MAX,
skip: 0,
props: {
isRoot: true,
},

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import OnCallDutyPolicyStatus from "Common/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
@@ -23,7 +22,7 @@ RunCron(
const fiveMinsAgo: Date = OneUptimeDate.getSomeMinutesAgo(5);
const stuckExecutions: Array<OnCallDutyPolicyExecutionLog> =
await OnCallDutyPolicyExecutionLogService.findBy({
await OnCallDutyPolicyExecutionLogService.findAllBy({
query: {
status: OnCallDutyPolicyStatus.Started,
createdAt: QueryHelper.lessThan(fiveMinsAgo),
@@ -32,8 +31,6 @@ RunCron(
_id: true,
createdAt: true,
},
limit: LIMIT_MAX,
skip: 0,
props: {
isRoot: true,
},
@@ -41,7 +38,7 @@ RunCron(
// check for executing logs more than 3 hours ago and mark them as timed out.
const stuckExecutingLogs: Array<OnCallDutyPolicyExecutionLog> =
await OnCallDutyPolicyExecutionLogService.findBy({
await OnCallDutyPolicyExecutionLogService.findAllBy({
query: {
status: OnCallDutyPolicyStatus.Executing,
createdAt: QueryHelper.lessThan(OneUptimeDate.getSomeHoursAgo(3)),
@@ -50,8 +47,6 @@ RunCron(
_id: true,
createdAt: true,
},
limit: LIMIT_MAX,
skip: 0,
props: {
isRoot: true,
},

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
import logger from "Common/Server/Utils/Logger";
import OneUptimeDate from "Common/Types/Date";
@@ -7,6 +6,8 @@ import QueryHelper from "Common/Server/Types/Database/QueryHelper";
import OnCallDutyPolicySchedule from "Common/Models/DatabaseModels/OnCallDutyPolicySchedule";
import OnCallDutyPolicyScheduleService from "Common/Server/Services/OnCallDutyPolicyScheduleService";
const ON_CALL_SCHEDULE_BATCH_SIZE: number = 100;
RunCron(
"OnCallDutySchedule:RefreshHandoffTime",
{ schedule: EVERY_MINUTE, runOnStartup: false },
@@ -14,7 +15,7 @@ RunCron(
logger.debug("Starting cron job: OnCallDutySchedule:RefreshHandoffTime");
const onCallScheduleWithHandoffTimeInPast: Array<OnCallDutyPolicySchedule> =
await OnCallDutyPolicyScheduleService.findBy({
await OnCallDutyPolicyScheduleService.findAllBy({
query: {
rosterHandoffAt: QueryHelper.lessThanEqualTo(
OneUptimeDate.getCurrentDate(),
@@ -31,10 +32,10 @@ RunCron(
nextUserIdOnRoster: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
batchSize: ON_CALL_SCHEDULE_BATCH_SIZE,
});
logger.debug(
@@ -42,7 +43,7 @@ RunCron(
);
const nextRosterStartTimeInPastSchedules: Array<OnCallDutyPolicySchedule> =
await OnCallDutyPolicyScheduleService.findBy({
await OnCallDutyPolicyScheduleService.findAllBy({
query: {
rosterNextStartAt: QueryHelper.lessThanEqualTo(
OneUptimeDate.getCurrentDate(),
@@ -60,10 +61,10 @@ RunCron(
nextUserIdOnRoster: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
batchSize: ON_CALL_SCHEDULE_BATCH_SIZE,
});
logger.debug(

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import { EVERY_DAY } from "Common/Utils/CronTime";
import logger from "Common/Server/Utils/Logger";
import OneUptimeDate from "Common/Types/Date";
@@ -7,6 +6,8 @@ import QueryHelper from "Common/Server/Types/Database/QueryHelper";
import OnCallDutyPolicyTimeLogService from "Common/Server/Services/OnCallDutyPolicyTimeLogService";
import { IsBillingEnabled } from "Common/Server/EnvironmentConfig";
const TIME_LOG_DELETE_BATCH_SIZE: number = 100;
RunCron(
"OnCallDuty:DeleteOldTimeLogs",
{ schedule: EVERY_DAY, runOnStartup: true },
@@ -22,15 +23,21 @@ RunCron(
// get time logs older than 6 months. EndsAt is more than 6 months ago.
await OnCallDutyPolicyTimeLogService.deleteBy({
query: {
endsAt: QueryHelper.lessThanEqualTo(sixMonthsAgo),
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
});
while (true) {
const deletedCount: number = await OnCallDutyPolicyTimeLogService.deleteBy({
query: {
endsAt: QueryHelper.lessThanEqualTo(sixMonthsAgo),
},
props: {
isRoot: true,
},
limit: TIME_LOG_DELETE_BATCH_SIZE,
skip: 0,
});
if (deletedCount === 0) {
break;
}
}
},
);

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import SubscriptionStatus from "Common/Types/Billing/SubscriptionStatus";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Sleep from "Common/Types/Sleep";
import { EVERY_DAY, EVERY_MINUTE } from "Common/Utils/CronTime";
import {
@@ -21,7 +20,7 @@ RunCron(
return;
}
const projects: Array<Project> = await ProjectService.findBy({
const projects: Array<Project> = await ProjectService.findAllBy({
query: {},
select: {
_id: true,
@@ -29,8 +28,6 @@ RunCron(
paymentProviderMeteredSubscriptionId: true,
paymentProviderCustomerId: true,
},
limit: LIMIT_MAX,
skip: 0,
props: {
isRoot: true,
ignoreHooks: true,

View File

@@ -2,7 +2,6 @@ import RunCron from "../../Utils/Cron";
import SubscriptionPlan, {
PlanType,
} from "Common/Types/Billing/SubscriptionPlan";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import { EVERY_WEEK } from "Common/Utils/CronTime";
import { IsBillingEnabled } from "Common/Server/EnvironmentConfig";
import ProjectService from "Common/Server/Services/ProjectService";
@@ -19,7 +18,7 @@ RunCron(
return;
}
const projects: Array<Project> = await ProjectService.findBy({
const projects: Array<Project> = await ProjectService.findAllBy({
query: {
planName: QueryHelper.isNull(),
},
@@ -27,8 +26,6 @@ RunCron(
_id: true,
paymentProviderPlanId: true,
},
limit: LIMIT_MAX,
skip: 0,
props: {
isRoot: true,
ignoreHooks: true,

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import SubscriptionStatus from "Common/Types/Billing/SubscriptionStatus";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import { EVERY_DAY, EVERY_MINUTE } from "Common/Utils/CronTime";
import {
IsBillingEnabled,
@@ -13,6 +12,8 @@ import User from "Common/Models/DatabaseModels/User";
import MailService from "Common/Server/Services/MailService";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
const SUBSCRIPTION_BATCH_SIZE: number = 100;
RunCron(
"PaymentProvider:SendDailyEmailsToOwnersIfSubscriptionIsOverdue",
{ schedule: IsDevelopment ? EVERY_MINUTE : EVERY_DAY, runOnStartup: false },
@@ -23,7 +24,7 @@ RunCron(
}
const merteredSubscriptionPastdue: Array<Project> =
await ProjectService.findBy({
await ProjectService.findAllBy({
query: {
paymentProviderMeteredSubscriptionStatus: SubscriptionStatus.PastDue,
},
@@ -32,15 +33,16 @@ RunCron(
paymentProviderSubscriptionId: true,
paymentProviderMeteredSubscriptionId: true,
},
limit: LIMIT_MAX,
skip: 0,
props: {
isRoot: true,
ignoreHooks: true,
},
skip: 0,
batchSize: SUBSCRIPTION_BATCH_SIZE,
});
const subscriptionPastdue: Array<Project> = await ProjectService.findBy({
const subscriptionPastdue: Array<Project> =
await ProjectService.findAllBy({
query: {
paymentProviderSubscriptionStatus: SubscriptionStatus.PastDue,
},
@@ -49,12 +51,12 @@ RunCron(
paymentProviderSubscriptionId: true,
paymentProviderMeteredSubscriptionId: true,
},
limit: LIMIT_MAX,
skip: 0,
props: {
isRoot: true,
ignoreHooks: true,
},
skip: 0,
batchSize: SUBSCRIPTION_BATCH_SIZE,
});
const allPastDueProjects: Array<Project> = [

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import { EVERY_DAY, EVERY_MINUTE } from "Common/Utils/CronTime";
import { IsDevelopment } from "Common/Server/EnvironmentConfig";
import ProjectService from "Common/Server/Services/ProjectService";
@@ -11,7 +10,7 @@ RunCron(
"PaymentProvider:UpdateTeamMembersIfNull",
{ schedule: IsDevelopment ? EVERY_MINUTE : EVERY_DAY, runOnStartup: false },
async () => {
const projects: Array<Project> = await ProjectService.findBy({
const projects: Array<Project> = await ProjectService.findAllBy({
query: {
paymentProviderSubscriptionSeats: QueryHelper.isNull(),
},
@@ -21,8 +20,6 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
});
for (const project of projects) {

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -27,15 +26,13 @@ RunCron(
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const probeOwnerTeams: Array<ProbeOwnerTeam> =
await ProbeOwnerTeamService.findBy({
await ProbeOwnerTeamService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
probeId: true,
@@ -74,15 +71,13 @@ RunCron(
}
const probeOwnerUsers: Array<ProbeOwnerUser> =
await ProbeOwnerUserService.findBy({
await ProbeOwnerUserService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
probeId: true,

View File

@@ -1,6 +1,5 @@
import OneUptimeDate from "Common/Types/Date";
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
import ProbeService from "Common/Server/Services/ProbeService";
import logger from "Common/Server/Utils/Logger";
@@ -14,7 +13,7 @@ RunCron(
async () => {
logger.debug("Checking Probe:UpdateConnectionStatus");
const probes: Array<Probe> = await ProbeService.findBy({
const probes: Array<Probe> = await ProbeService.findAllBy({
query: {},
props: {
isRoot: true,
@@ -25,8 +24,6 @@ RunCron(
connectionStatus: true,
projectId: true,
},
limit: LIMIT_MAX,
skip: 0,
});
logger.debug(`Found ${probes.length} probes`);

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
import ScheduledMaintenanceService from "Common/Server/Services/ScheduledMaintenanceService";
@@ -14,7 +13,7 @@ RunCron(
async () => {
// get all scheduled events of all the projects.
const events: Array<ScheduledMaintenance> =
await ScheduledMaintenanceService.findBy({
await ScheduledMaintenanceService.findAllBy({
query: {
currentScheduledMaintenanceState: {
isOngoingState: true,
@@ -24,8 +23,6 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
projectId: true,

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
import ScheduledMaintenanceService from "Common/Server/Services/ScheduledMaintenanceService";
@@ -14,7 +13,7 @@ RunCron(
async () => {
// get all scheduled events of all the projects.
const events: Array<ScheduledMaintenance> =
await ScheduledMaintenanceService.findBy({
await ScheduledMaintenanceService.findAllBy({
query: {
currentScheduledMaintenanceState: {
isScheduledState: true,
@@ -24,8 +23,6 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
projectId: true,

View File

@@ -2,7 +2,6 @@ import { EVERY_DAY } from "Common/Utils/CronTime";
import RunCron from "../../Utils/Cron";
import logger from "Common/Server/Utils/Logger";
import ProjectService from "Common/Server/Services/ProjectService";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import ScheduledMaintenanceService from "Common/Server/Services/ScheduledMaintenanceService";
import Project from "Common/Models/DatabaseModels/Project";
import ScheduledMaintenance from "Common/Models/DatabaseModels/ScheduledMaintenance";
@@ -17,19 +16,12 @@ RunCron(
* if they are different, then update the current state of the scheduled maintenance.
*/
const projects: Array<Project> = await ProjectService.findBy({
query: {
...ProjectService.getActiveProjectStatusQuery(),
},
select: {
_id: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},
});
const projects: Array<Project> =
await ProjectService.getAllActiveProjects({
select: {
_id: true,
},
});
for (const project of projects) {
try {
@@ -42,15 +34,13 @@ RunCron(
}
const scheduledMaintenances: Array<ScheduledMaintenance> =
await ScheduledMaintenanceService.findBy({
await ScheduledMaintenanceService.findAllBy({
query: {
projectId: project.id,
},
select: {
_id: true,
},
skip: 0,
limit: LIMIT_MAX,
props: {
isRoot: true,
},

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
import ScheduledMaintenanceService from "Common/Server/Services/ScheduledMaintenanceService";
@@ -25,7 +24,7 @@ RunCron(
// get all scheduled events of all the projects.
const recurringTemplates: Array<ScheduledMaintenanceTemplate> =
await ScheduledMaintenanceTemplateService.findBy({
await ScheduledMaintenanceTemplateService.findAllBy({
query: {
isRecurringEvent: true,
scheduleNextEventAt: QueryHelper.lessThanEqualTo(
@@ -35,8 +34,6 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
projectId: true,
@@ -92,15 +89,13 @@ RunCron(
// get owner users for this template.
const ownerUsers: Array<ScheduledMaintenanceTemplateOwnerUser> =
await ScheduledMaintenanceTemplateOwnerUserService.findBy({
await ScheduledMaintenanceTemplateOwnerUserService.findAllBy({
query: {
scheduledMaintenanceTemplateId: recurringTemplate.id!,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
userId: true,
},
@@ -108,15 +103,13 @@ RunCron(
// owner teams.
const ownerTeams: Array<ScheduledMaintenanceOwnerTeam> =
await ScheduledMaintenanceTemplateOwnerTeamService.findBy({
await ScheduledMaintenanceTemplateOwnerTeamService.findAllBy({
query: {
scheduledMaintenanceTemplateId: recurringTemplate.id!,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
teamId: true,
},

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
import ScheduledMaintenance from "Common/Models/DatabaseModels/ScheduledMaintenance";
import ScheduledMaintenanceService from "Common/Server/Services/ScheduledMaintenanceService";
@@ -15,7 +14,7 @@ RunCron(
async () => {
// get all scheduled events of all the projects.
const scheduledEvents: Array<ScheduledMaintenance> =
await ScheduledMaintenanceService.findBy({
await ScheduledMaintenanceService.findAllBy({
query: {
subscriberNotificationStatusOnEventScheduled:
StatusPageSubscriberNotificationStatus.Pending,
@@ -24,8 +23,6 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
title: true,

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
import QueryHelper from "Common/Server/Types/Database/QueryHelper";
@@ -19,7 +18,7 @@ RunCron(
);
// get all scheduled events of all the projects.
const scheduledEvents: Array<ScheduledMaintenance> =
await ScheduledMaintenanceService.findBy({
await ScheduledMaintenanceService.findAllBy({
query: {
nextSubscriberNotificationBeforeTheEventAt: QueryHelper.lessThan(
OneUptimeDate.getCurrentDate(),
@@ -28,8 +27,6 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
title: true,

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -22,20 +21,21 @@ import ObjectID from "Common/Types/ObjectID";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const OWNER_NOTIFICATION_BATCH_SIZE: number = 100;
RunCron(
"ScheduledMaintenanceOwner:SendCreatedResourceEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
// get all scheduled events of all the projects.
const scheduledMaintenances: Array<ScheduledMaintenance> =
await ScheduledMaintenanceService.findBy({
await ScheduledMaintenanceService.findAllBy({
query: {
isOwnerNotifiedOfResourceCreation: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -50,6 +50,7 @@ RunCron(
},
scheduledMaintenanceNumber: true,
},
batchSize: OWNER_NOTIFICATION_BATCH_SIZE,
});
for (const scheduledMaintenance of scheduledMaintenances) {

View File

@@ -1,7 +1,6 @@
import RunCron from "../../Utils/Cron";
import BaseModel from "Common/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -27,19 +26,20 @@ import { Blue500 } from "Common/Types/BrandColors";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const NOTE_NOTIFICATION_BATCH_SIZE: number = 100;
RunCron(
"ScheduledMaintenanceOwner:SendsNotePostedEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const publicNotes: Array<ScheduledMaintenancePublicNote> =
await ScheduledMaintenancePublicNoteService.findBy({
await ScheduledMaintenancePublicNoteService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -47,17 +47,17 @@ RunCron(
scheduledMaintenanceId: true,
projectId: true,
},
batchSize: NOTE_NOTIFICATION_BATCH_SIZE,
});
const privateNotes: Array<ScheduledMaintenanceInternalNote> =
await ScheduledMaintenanceInternalNoteService.findBy({
await ScheduledMaintenanceInternalNoteService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -65,6 +65,7 @@ RunCron(
scheduledMaintenanceId: true,
projectId: true,
},
batchSize: NOTE_NOTIFICATION_BATCH_SIZE,
});
const privateNoteIds: Array<string> = privateNotes.map(

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -23,25 +22,27 @@ import User from "Common/Models/DatabaseModels/User";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const OWNER_BATCH_SIZE: number = 100;
RunCron(
"ScheduledMaintenanceOwner:SendOwnerAddedEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const scheduledMaintenanceOwnerTeams: Array<ScheduledMaintenanceOwnerTeam> =
await ScheduledMaintenanceOwnerTeamService.findBy({
await ScheduledMaintenanceOwnerTeamService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
scheduledMaintenanceId: true,
teamId: true,
},
batchSize: OWNER_BATCH_SIZE,
});
const scheduledMaintenanceOwnersMap: Dictionary<Array<User>> = {};
@@ -83,14 +84,13 @@ RunCron(
}
const scheduledMaintenanceOwnerUsers: Array<ScheduledMaintenanceOwnerUser> =
await ScheduledMaintenanceOwnerUserService.findBy({
await ScheduledMaintenanceOwnerUserService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -101,6 +101,7 @@ RunCron(
name: true,
},
},
batchSize: OWNER_BATCH_SIZE,
});
for (const scheduledMaintenanceOwnerUser of scheduledMaintenanceOwnerUsers) {

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
@@ -28,6 +27,8 @@ import UserService from "Common/Server/Services/UserService";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const STATE_CHANGE_BATCH_SIZE: number = 100;
RunCron(
"ScheduledMaintenanceOwner:SendStateChangeEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
@@ -35,14 +36,13 @@ RunCron(
// get all scheduled events of all the projects.
const scheduledMaintenanceStateTimelines: Array<ScheduledMaintenanceStateTimeline> =
await ScheduledMaintenanceStateTimelineService.findBy({
await ScheduledMaintenanceStateTimelineService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -63,6 +63,7 @@ RunCron(
name: true,
},
},
batchSize: STATE_CHANGE_BATCH_SIZE,
});
for (const scheduledMaintenanceStateTimeline of scheduledMaintenanceStateTimelines) {

View File

@@ -3,7 +3,7 @@ import { FileRoute } from "Common/ServiceRoute";
import Hostname from "Common/Types/API/Hostname";
import Protocol from "Common/Types/API/Protocol";
import URL from "Common/Types/API/URL";
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import Dictionary from "Common/Types/Dictionary";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -39,6 +39,8 @@ import { Blue500 } from "Common/Types/BrandColors";
import SlackUtil from "Common/Server/Utils/Workspace/Slack/Slack";
import MicrosoftTeamsUtil from "Common/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams";
const PUBLIC_NOTE_BATCH_SIZE: number = 100;
RunCron(
"ScheduledMaintenancePublicNote:SendNotificationToSubscribers",
{ schedule: EVERY_MINUTE, runOnStartup: false },
@@ -49,7 +51,7 @@ RunCron(
const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
const publicNotes: Array<ScheduledMaintenancePublicNote> =
await ScheduledMaintenancePublicNoteService.findBy({
await ScheduledMaintenancePublicNoteService.findAllBy({
query: {
subscriberNotificationStatusOnNoteCreated:
StatusPageSubscriberNotificationStatus.Pending,
@@ -58,13 +60,13 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
note: true,
scheduledMaintenanceId: true,
},
batchSize: PUBLIC_NOTE_BATCH_SIZE,
});
logger.debug(
@@ -160,7 +162,7 @@ RunCron(
let statusPageResources: Array<StatusPageResource> = [];
if (event.monitors && event.monitors.length > 0) {
statusPageResources = await StatusPageResourceService.findBy({
statusPageResources = await StatusPageResourceService.findAllBy({
query: {
monitorId: QueryHelper.any(
event.monitors
@@ -177,12 +179,12 @@ RunCron(
ignoreHooks: true,
},
skip: 0,
limit: LIMIT_PER_PROJECT,
select: {
_id: true,
displayName: true,
statusPageId: true,
},
batchSize: LIMIT_PER_PROJECT,
});
}

View File

@@ -3,7 +3,7 @@ import { FileRoute } from "Common/ServiceRoute";
import Hostname from "Common/Types/API/Hostname";
import Protocol from "Common/Types/API/Protocol";
import URL from "Common/Types/API/URL";
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import Dictionary from "Common/Types/Dictionary";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -47,7 +47,7 @@ RunCron(
const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
const scheduledEventStateTimelines: Array<ScheduledMaintenanceStateTimeline> =
await ScheduledMaintenanceStateTimelineService.findBy({
await ScheduledMaintenanceStateTimelineService.findAllBy({
query: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Pending,
@@ -56,8 +56,6 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
scheduledMaintenanceId: true,

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import { CheckOn } from "Common/Types/Monitor/CriteriaFilter";
import MonitorType from "Common/Types/Monitor/MonitorType";
@@ -11,6 +10,8 @@ import logger from "Common/Server/Utils/Logger";
import MonitorResourceUtil from "Common/Server/Utils/Monitor/MonitorResource";
import Monitor from "Common/Models/DatabaseModels/Monitor";
import ProjectService from "Common/Server/Services/ProjectService";
const SERVER_MONITOR_BATCH_SIZE: number = 100;
RunCron(
"ServerMonitor:CheckOnlineStatus",
{ schedule: EVERY_MINUTE, runOnStartup: false },
@@ -18,7 +19,7 @@ RunCron(
try {
const threeMinsAgo: Date = OneUptimeDate.getSomeMinutesAgo(3);
const serverMonitors: Array<Monitor> = await MonitorService.findBy({
const serverMonitors: Array<Monitor> = await MonitorService.findAllBy({
query: {
monitorType: MonitorType.Server,
serverMonitorRequestReceivedAt:
@@ -35,8 +36,8 @@ RunCron(
_id: true,
monitorSteps: true,
},
limit: LIMIT_MAX,
skip: 0,
batchSize: SERVER_MONITOR_BATCH_SIZE,
});
// Prepare all monitor resource tasks for parallel processing

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import Recurring from "Common/Types/Events/Recurring";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
@@ -8,6 +7,8 @@ import QueryHelper from "Common/Server/Types/Database/QueryHelper";
import logger from "Common/Server/Utils/Logger";
import StatusPage from "Common/Models/DatabaseModels/StatusPage";
const STATUS_PAGE_REPORT_BATCH_SIZE: number = 100;
RunCron(
"StatusPage:SendReportToSubscribers",
{
@@ -17,7 +18,7 @@ RunCron(
async () => {
// get all scheduled events of all the projects.
const statusPageToSendReports: Array<StatusPage> =
await StatusPageService.findBy({
await StatusPageService.findAllBy({
query: {
isReportEnabled: true,
sendNextReportBy: QueryHelper.lessThan(
@@ -27,13 +28,13 @@ RunCron(
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
sendNextReportBy: true,
reportRecurringInterval: true,
},
batchSize: STATUS_PAGE_REPORT_BATCH_SIZE,
});
for (const statusPageToSendReport of statusPageToSendReports) {

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -21,19 +20,20 @@ import User from "Common/Models/DatabaseModels/User";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const ANNOUNCEMENT_OWNER_BATCH_SIZE: number = 100;
RunCron(
"StatusPageOwner:SendAnnouncementCreatedEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const announcements: Array<StatusPageAnnouncement> =
await StatusPageAnnouncementService.findBy({
await StatusPageAnnouncementService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -46,6 +46,7 @@ RunCron(
projectId: true,
},
},
batchSize: ANNOUNCEMENT_OWNER_BATCH_SIZE,
});
for (const announcement of announcements) {

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -18,19 +17,20 @@ import User from "Common/Models/DatabaseModels/User";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const STATUS_PAGE_OWNER_BATCH_SIZE: number = 100;
RunCron(
"StatusPageOwner:SendCreatedResourceEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
// get all scheduled events of all the projects.
const statusPages: Array<StatusPage> = await StatusPageService.findBy({
const statusPages: Array<StatusPage> = await StatusPageService.findAllBy({
query: {
isOwnerNotifiedOfResourceCreation: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -41,6 +41,7 @@ RunCron(
name: true,
},
},
batchSize: STATUS_PAGE_OWNER_BATCH_SIZE,
});
for (const statusPage of statusPages) {

View File

@@ -1,6 +1,5 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
@@ -23,25 +22,27 @@ import User from "Common/Models/DatabaseModels/User";
import { createWhatsAppMessageFromTemplate } from "Common/Server/Utils/WhatsAppTemplateUtil";
import { WhatsAppMessagePayload } from "Common/Types/WhatsApp/WhatsAppMessage";
const STATUS_PAGE_OWNER_BATCH_SIZE: number = 100;
RunCron(
"StatusPageOwner:SendOwnerAddedEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const statusPageOwnerTeams: Array<StatusPageOwnerTeam> =
await StatusPageOwnerTeamService.findBy({
await StatusPageOwnerTeamService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
statusPageId: true,
teamId: true,
},
batchSize: STATUS_PAGE_OWNER_BATCH_SIZE,
});
const statusPageOwnersMap: Dictionary<Array<User>> = {};
@@ -77,14 +78,13 @@ RunCron(
}
const statusPageOwnerUsers: Array<StatusPageOwnerUser> =
await StatusPageOwnerUserService.findBy({
await StatusPageOwnerUserService.findAllBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
@@ -95,6 +95,7 @@ RunCron(
name: true,
},
},
batchSize: STATUS_PAGE_OWNER_BATCH_SIZE,
});
for (const statusPageOwnerUser of statusPageOwnerUsers) {

View File

@@ -1,6 +1,6 @@
import OneUptimeDate from "Common/Types/Date";
import RunCron from "../../Utils/Cron";
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import MonitorType from "Common/Types/Monitor/MonitorType";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
import MonitorService from "Common/Server/Services/MonitorService";
@@ -43,7 +43,7 @@ RunCron(
async () => {
logger.debug("Checking TelemetryMonitor:MonitorTelemetryMonitor");
const telemetryMonitors: Array<Monitor> = await MonitorService.findBy({
const telemetryMonitors: Array<Monitor> = await MonitorService.findAllBy({
query: {
disableActiveMonitoring: false,
disableActiveMonitoringBecauseOfScheduledMaintenanceEvent: false,
@@ -70,8 +70,6 @@ RunCron(
monitorType: true,
projectId: true,
},
limit: LIMIT_MAX,
skip: 0,
});
const updatePromises: Array<Promise<void>> = [];

View File

@@ -1,5 +1,5 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import NotificationRuleType from "Common/Types/NotificationRule/NotificationRuleType";
import UserNotificationExecutionStatus from "Common/Types/UserNotification/UserNotificationExecutionStatus";
@@ -23,7 +23,7 @@ RunCron(
},
async () => {
const pendingNotificationLogs: Array<UserOnCallLog> =
await UserOnCallLogService.findBy({
await UserOnCallLogService.findAllBy({
query: {
status: UserNotificationExecutionStatus.Executing,
},
@@ -46,8 +46,7 @@ RunCron(
props: {
isRoot: true,
},
skip: 0,
limit: LIMIT_MAX,
batchSize: LIMIT_PER_PROJECT,
});
const promises: Array<Promise<void>> = [];

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import UserNotificationExecutionStatus from "Common/Types/UserNotification/UserNotificationExecutionStatus";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
@@ -8,6 +7,8 @@ import UserOnCallLogService from "Common/Server/Services/UserOnCallLogService";
import QueryHelper from "Common/Server/Types/Database/QueryHelper";
import UserOnCallLog from "Common/Models/DatabaseModels/UserOnCallLog";
const ON_CALL_TIMEOUT_BATCH_SIZE: number = 100;
/**
* Jobs move from Started to Executing in seconds. If it takes more than 5 minutes, it's stuck. So, mark them as error
*/
@@ -23,7 +24,7 @@ RunCron(
const fiveMinsAgo: Date = OneUptimeDate.getSomeMinutesAgo(5);
const stuckExecutions: Array<UserOnCallLog> =
await UserOnCallLogService.findBy({
await UserOnCallLogService.findAllBy({
query: {
status: UserNotificationExecutionStatus.Started,
createdAt: QueryHelper.lessThan(fiveMinsAgo),
@@ -32,16 +33,16 @@ RunCron(
_id: true,
createdAt: true,
},
limit: LIMIT_MAX,
skip: 0,
props: {
isRoot: true,
},
batchSize: ON_CALL_TIMEOUT_BATCH_SIZE,
});
// check for executing logs more than 3 hours ago and mark them as timed out.
const stuckExecutingLogs: Array<UserOnCallLog> =
await UserOnCallLogService.findBy({
await UserOnCallLogService.findAllBy({
query: {
status: UserNotificationExecutionStatus.Executing,
createdAt: QueryHelper.lessThan(OneUptimeDate.getSomeHoursAgo(3)),
@@ -50,11 +51,11 @@ RunCron(
_id: true,
createdAt: true,
},
limit: LIMIT_MAX,
skip: 0,
props: {
isRoot: true,
},
batchSize: ON_CALL_TIMEOUT_BATCH_SIZE,
});
const totalStuckExecutions: Array<UserOnCallLog> = [

View File

@@ -1,5 +1,4 @@
import RunCron from "../../Utils/Cron";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import OneUptimeDate from "Common/Types/Date";
import WorkflowStatus from "Common/Types/Workflow/WorkflowStatus";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
@@ -7,18 +6,19 @@ import WorkflowLogService from "Common/Server/Services/WorkflowLogService";
import QueryHelper from "Common/Server/Types/Database/QueryHelper";
import WorkflowLog from "Common/Models/DatabaseModels/WorkflowLog";
const WORKFLOW_TIMEOUT_BATCH_SIZE: number = 100;
RunCron(
"Workflow:TimeoutJobs",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
// Timeout all workflows that have been scheduled for more than 5 minutes
const stalledWorkflowLogs: Array<WorkflowLog> =
await WorkflowLogService.findBy({
await WorkflowLogService.findAllBy({
query: {
createdAt: QueryHelper.lessThan(OneUptimeDate.getSomeMinutesAgo(5)),
workflowStatus: WorkflowStatus.Scheduled,
},
limit: LIMIT_MAX,
select: {
logs: true,
_id: true,
@@ -27,6 +27,7 @@ RunCron(
props: {
isRoot: true,
},
batchSize: WORKFLOW_TIMEOUT_BATCH_SIZE,
});
for (const stalledWorkflowLog of stalledWorkflowLogs) {