Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api,worker): timed digest logic #3359

Conversation

LetItRock
Copy link
Contributor

What change does this PR introduce?

In this PR:

  1. API/Worker changes:
  • the Timed Digest logic that calculates the job delay by using the class from the private package
  • updated job schema
  • updated swagger API types
  1. FE changes:
  • fixed missing timed digest form field names
  • use shared enums instead of strings

Tests will be added in a separate PR.

Link to the related enterprise package PR: https://github.com/novuhq/packages-enterprise/pull/2

Why was this change needed?

This PR is a part of the Timed Digest feature.

Other information (Screenshots)

@LetItRock LetItRock self-assigned this May 8, 2023
@linear
Copy link

linear bot commented May 8, 2023

@LetItRock LetItRock force-pushed the nv-2221-update-digesting-logic-to-support-scheduled-type-main branch from 82be2a5 to 089581c Compare May 8, 2023 23:51
@@ -27,6 +28,7 @@ export const USE_CASES = [
DigestFilterSteps,
DigestFilterStepsRegular,
DigestFilterStepsBackoff,
DigestFilterStepsTimed,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the new use-case to filter steps for the timed digest

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both worker/api are using it... the api app uses it because of the batch endpoint... the worker app has the logic to handle the trigger events from the queue and parse to the jobs

Comment on lines +33 to +40
@ApiPropertyOptional({ enum: [...Object.values(OrdinalEnum)] })
ordinal?: OrdinalEnum;

@ApiPropertyOptional()
ordinalValue?: string;
@ApiPropertyOptional({ enum: [...Object.values(OrdinalValueEnum)] })
ordinalValue?: OrdinalValueEnum;

@ApiPropertyOptional()
monthlyType?: string;
@ApiPropertyOptional({ enum: [...Object.values(MonthlyTypeEnum)] })
monthlyType?: MonthlyTypeEnum;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated swagger enums and values

<Radio.Group spacing={0} defaultValue="each" value={radioGroup.value} onChange={radioGroup.onChange}>
<Radio.Group
spacing={0}
defaultValue={MonthlyTypeEnum.EACH}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use enums instead of strings

Comment on lines +59 to +61
const atTime = watch(`steps.${index}.metadata.timed.atTime`);
const weekDays = watch(`steps.${index}.metadata.timed.weekDays`) || [];
const monthDays = watch(`steps.${index}.metadata.timed.monthDays`) || [];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated names for these fields that were missed in previous PR

Comment on lines +89 to +104
timed: {
atTime: {
type: Schema.Types.String,
},
weekDays: [Schema.Types.String],
monthDays: [Schema.Types.Number],
ordinal: {
type: Schema.Types.String,
},
ordinalValue: {
type: Schema.Types.String,
},
monthlyType: {
type: Schema.Types.String,
},
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated job schema

Comment on lines 62 to 75
if (IS_ENTERPRISE && stepMetadata.type === DigestTypeEnum.TIMED) {
const timedDigestMeta = stepMetadata as IDigestTimedMetadata;

// eslint-disable-next-line @typescript-eslint/naming-convention
const { TimedDigestDelayService } = require('@novu/digest-schedule');

return TimedDigestDelayService.calculate({
unit: timedDigestMeta.unit,
amount: timedDigestMeta.amount,
atTime: timedDigestMeta.timed?.atTime,
weekDays: timedDigestMeta.timed?.weekDays,
monthDays: timedDigestMeta.timed?.monthDays,
});
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the calculations for the timed digest delay

@@ -46,32 +44,11 @@ export class AddDigestJob {
): Promise<AddDigestJobResult> {
const { job } = command;

this.validateDigest(job);
validateDigest(job);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to the helper functions outside


// TODO: timed digest
if (
this.isRegularDigest(job.digest.type) &&
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed this check that I've added before

@@ -0,0 +1,127 @@
import {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the validation helper functions to check the digest metadata values

import { DigestFilterSteps } from './digest-filter-steps.usecase';

@Injectable()
export class DigestFilterStepsTimed {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the use-case to filter steps for the timed digest run... basically at first trigger we will create all the jobs from the template steps; on subsequent triggers if digest is running we will only create the jobs from the steps that are before the digest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this different from the regular backoff?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not much but I've improved it a little.

The regular digest filter use-case: always creates a jobs array based on template steps, even if there is a digest job delayed, and then when the digest is running it marks all other digest jobs as completed. This leads to other jobs in the pending state forever.

The timed digest filter use-case: obviously creates jobs based on the template steps, but it checks if there is a delayed timed digest job, and if there is it just creates a jobs array from the steps that are before the digest, so like it cuts the jobs array.

I've asked this question before on the Discord, but no one has answered it: https://discord.com/channels/895029566685462578/1045289346598703164/1096406448839331941

return 0;
}

toMilliseconds(amount: number, unit: DigestUnitEnum): number {
private toMilliseconds(amount: number, unit: DigestUnitEnum): number {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we make this private?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it's not used anywhere now only internally

enterprise/packages Outdated Show resolved Hide resolved
Comment on lines +49 to +55
SUNDAY = 'sunday',
MONDAY = 'monday',
TUESDAY = 'tuesday',
WEDNESDAY = 'wednesday',
THURSDAY = 'thursday',
FRIDAY = 'friday',
SATURDAY = 'saturday',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we plan to use this Enum values? Mostly as day names should be capitalised.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This enum is reused between FE/BE.
On the FE we do use it as values for the dropdown, but the labels are capitalized.
On the BE we do have validation for the request value to be one of the enum values, also it is used for the timed digest calculations.

Base automatically changed from nv-2226-update-digest-metadata-types to timed-digest May 10, 2023 10:37
@LetItRock LetItRock merged commit 1f56352 into timed-digest May 10, 2023
29 checks passed
@LetItRock LetItRock deleted the nv-2221-update-digesting-logic-to-support-scheduled-type-main branch May 10, 2023 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants