Skip to content

Entry points for recurring jobs #322

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

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from

Conversation

br648
Copy link
Contributor

@br648 br648 commented May 1, 2025

Checklist

  • Appropriate branch selected (all PRs must first be merged to dev before they can be merged to master)
  • Any modified or new methods or classes have helpful JavaDoc and code is thoroughly commented
  • The description lists all applicable issues this PR seeks to resolve
  • The description lists any configuration setting(s) that differ from the default settings
  • All tests and CI builds passing

Description

This PR seeks to allow fine grain control over the jobs within the OTP middleware which should be started. This will then allow various instances of OTP middleware to be started which focus on specific jobs instead of all jobs running under a single instance.

It should be backwards compatiable, e.g. defining no parameters or defining just a config file should allow everything to start under the one instance.

Copy link
Collaborator

@binh-dam-ibigroup binh-dam-ibigroup left a comment

Choose a reason for hiding this comment

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

First round of comments. I still need to play around with the changes, but I would like to explore using cron for some recurring jobs.

if (command.equalsIgnoreCase("-recurringjobs")) {
defineRecurringJobs(commandValues);
}
if (command.equalsIgnoreCase("-loadbalance")) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Trying to find a better name for this option without having to reference load balancers... How about something like --endpoints-only or --api-endpoints because this serves the API endpoints only, correct? (so that a load balancer can dispatch web requests).

Copy link
Collaborator

Choose a reason for hiding this comment

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

For command line flags, we should probably follow the convention used by many Unix programs - typically double-dash + kebab-case-command (e.g. --load-balancer) and either one dash + one letter/number (e.g. -L) for shorthand syntax. (Note: OTP uses pascalCase commands as in --loadBalancer and that's ok if we want to adopt that.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My thinking was to keep this generic, so anything that could be load balanced would be covered. At the moment, the only item is the API, so will change it to suit this.

import java.util.stream.Collectors;
import java.util.stream.Stream;

public enum RecurringJob {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is probably okay as first approach. I had in mind that some recurring jobs should eventually be handled by the OS (e.g. cron) so that they can be started/terminated regardless of completion status.

if (!recurringJobs.isEmpty()) {
recurringJobs.forEach(RecurringJob::schedule);
try {
// Block the main thread until the scheduler is terminated to prevent the application from
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe this is why I'd prefer recurring jobs to be scheduled by the OS itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this isn't ideal. My approach for this first iteration was to not change the existing scheduled services. In the case of BugsnagJobs it actually schedules three different jobs with different parameters. Perhaps for a specific job (e.g. --cron-job) that qualifies, I can rearchitecture to have a Main entry point? We still need to consider backwards compatibility.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's fine to take it one step at a time.

Copy link
Collaborator

@binh-dam-ibigroup binh-dam-ibigroup left a comment

Choose a reason for hiding this comment

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

Moving in the right direction, but endpoints are not working at all as written. See also other suggestions.

return this;
}

public CommandLineTestCase withLoadBalanced(boolean isLoadBalanced) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Rename to withEndpoints (rename the parameter accordingly too).

private static class CommandLineTestCase {
public String configFile = DEFAULT_ENV;
public Set<RecurringJob> recurringJobs = RecurringJob.getAllRecurringJobs();
public boolean isLoadBalanced = true;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Rename to hasEndpoints.

}
}

if (processor.hasEndPoints()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Move this block to before the scheduler stuff. Otherwise, because of the thread blocking above, this block is never executed (until termination), and therefore no endpoints are available.

* Define if the end points should be enabled.
*/
private void defineEndPoints(Set<String> endPointArguments) {
if (endPointArguments.size() == 1 && endPointArguments.contains("yes")) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

In how the parsing code works, is it possible to just pass a --endpoint-only flag without the
"yes" or "no"? (so that --endpoints-only without a parameter implies "yes")

* /configurations/test/env.yml --endpoints-only yes --recurring-jobs monitor-all-trips-job
*/
public class CommandLineProcessor {
public static final List<String> END_POINTS_ONLY_FLAGS = List.of("--endpoints-only", "-E");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, rename to --endpoints because the flag is not meant to exclude the other features.

Comment on lines +46 to +48
if (RECURRING_JOB_FLAGS.contains(flag)) {
defineRecurringJobs(commandValues);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

To only enable the endpoints and run no recurring jobs, the command line would read --recurring-jobs, and that feels kinda strange. Maybe including a --recurring-jobs no or --recurring-jobs none in addition to just --recurring-jobs would help reduce confusion.


/**
* Parse the arguments provided on the command line. To maintain backward compatibility, if a config file is
* required, it must be the first argument and no command e.g. -config is NOT required.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
* required, it must be the first argument and no command e.g. -config is NOT required.
* required, it must be the first argument, and no flag (e.g. --config) is used.

Comment on lines +37 to +42
public static RecurringJob getJobFromCommandLineArgument(String commandLineArgument) {
return Arrays.stream(RecurringJob.values())
.filter(job -> job.commandLineName.equalsIgnoreCase(commandLineArgument))
.findFirst()
.orElse(null);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

How does this method differ from the native Enum.valueOf()?

}

public static Set<RecurringJob> getAllRecurringJobs() {
return new HashSet<>(Arrays.asList(RecurringJob.values()));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
return new HashSet<>(Arrays.asList(RecurringJob.values()));
return Set.of(RecurringJob.values());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants