-
Notifications
You must be signed in to change notification settings - Fork 3
SED-4157-executions history #577
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
base: master
Are you sure you want to change the base?
SED-4157-executions history #577
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
Summary of ChangesHello @lucianbaciu, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request implements a foundational feature for tracking and displaying the execution history of plans. It involves extending core data models to include canonical plan identifiers and historical result snapshots, introducing a new plugin to collect this data post-execution, and refining the execution engine's logic to correctly populate these new fields. These changes are crucial for providing users with insights into the performance and outcomes of their plans over time. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces functionality to track execution history by defining a canonical plan name. A new plugin is added to fetch and attach this history to executions. The changes are logical and well-implemented. My review includes suggestions to improve consistency in canonical name generation, remove dead code, make a hardcoded value configurable, and some minor code style improvements.
| // plan already exists in memory | ||
| canonicalPlanName = plan.getId().toString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a plan is passed directly in ExecutionParameters, the canonical plan name is set to the plan's ID. This can lead to inconsistencies if the same plan is sometimes imported (getting a canonical name from repository parameters) and sometimes passed directly. To ensure consistency, you should try to generate the canonical name from executionParameters.getRepositoryObject() if it's available, even when the plan object is already present. The current approach might result in fragmented execution histories for the same logical plan.
This will require adding import static step.core.repositories.AbstractRepository.getCanonicalPlanName; to the file.
// plan already exists in memory
RepositoryObjectReference repositoryObject = executionParameters.getRepositoryObject();
if (repositoryObject != null) {
canonicalPlanName = getCanonicalPlanName(repositoryObject.getRepositoryParameters());
} else {
canonicalPlanName = plan.getId().toString();
}|
|
||
| @Override | ||
| public void executionStart(ExecutionContext context) { | ||
| // TOOD collect the executions here too |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Execution execution = context.getExecutionManager().getExecution(); | ||
| // endTime is not set here | ||
| long searchBeforeTimestamp = System.currentTimeMillis() - 1; | ||
| List<ExecutionResultSnapshot> pastExecutionsSnapshots = executionAccessor.getLastEndedExecutionsByCanonicalPlanName(execution.getCanonicalPlanName(), 10, searchBeforeTimestamp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed, get the value from the configuration (step.properties) with a default value of 10.
| return repositoryParameters.entrySet().stream() | ||
| .sorted(Map.Entry.comparingByKey()) | ||
| .map(e -> e.getKey() + "=" + e.getValue()) | ||
| .collect(java.util.stream.Collectors.joining("&")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
@david-stephan please take a look on this before leaving in vacation, if you can. Ignore the cleanup/formatting part. Let me know if the approach is fine. |
david-stephan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lucianbaciu in addition to the feedback from Gemini which are valid too, please see my comments
| ExecutionAccessor executionAccessor = context.getExecutionAccessor(); | ||
| Execution execution = context.getExecutionManager().getExecution(); | ||
| // endTime is not set here | ||
| long searchBeforeTimestamp = System.currentTimeMillis() - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be true now, but can change in the future, you should first check the execution end time and only if not set set use the current time.
| Execution execution = context.getExecutionManager().getExecution(); | ||
| // endTime is not set here | ||
| long searchBeforeTimestamp = System.currentTimeMillis() - 1; | ||
| List<ExecutionResultSnapshot> pastExecutionsSnapshots = executionAccessor.getLastEndedExecutionsByCanonicalPlanName(execution.getCanonicalPlanName(), 10, searchBeforeTimestamp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed, get the value from the configuration (step.properties) with a default value of 10.
| // endTime is not set here | ||
| long searchBeforeTimestamp = System.currentTimeMillis() - 1; | ||
| List<ExecutionResultSnapshot> pastExecutionsSnapshots = executionAccessor.getLastEndedExecutionsByCanonicalPlanName(execution.getCanonicalPlanName(), 10, searchBeforeTimestamp) | ||
| .stream() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getLastEndedExecutionsByCanonicalPlanName should return a stream directly
| long searchBeforeTimestamp = System.currentTimeMillis() - 1; | ||
| List<ExecutionResultSnapshot> pastExecutionsSnapshots = executionAccessor.getLastEndedExecutionsByCanonicalPlanName(execution.getCanonicalPlanName(), 10, searchBeforeTimestamp) | ||
| .stream() | ||
| .map(e -> new ExecutionResultSnapshot() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think of the information you'll need to also display a tooltip, at least the execution start time would be required too
| return historyResults; | ||
| } | ||
|
|
||
| public Execution setHistoryResults(List<ExecutionResultSnapshot> historyResults) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use at standard setter, must be void
| try { | ||
| Plan plan = getPlanFromExecutionParametersOrImport(); | ||
| ExecutionParameters executionParameters = executionContext.getExecutionParameters(); | ||
| Plan plan = executionParameters.getPlan(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could simply check where we use the executionParameters.setPlan to see that this case is used for interactive execution (see startInteractiveSession in InteractiveServices), if you want more details or debug the case. This case is edgy and it would actually be cleaner and more correct to not create any historical statuses for them (or even ingest any time-series for them). For now I would then not set the canonical name and handle null value in the plugin
|
|
||
| public static String getCanonicalPlanName(Map<String, String> repositoryParameters) { | ||
| if (repositoryParameters == null || repositoryParameters.isEmpty()) { | ||
| return ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should return null to be consistent and let the caller know that no canonical name exist
| } | ||
|
|
||
| return repositoryParameters.entrySet().stream() | ||
| .sorted(Map.Entry.comparingByKey()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are not filtering by canonicalRepositoryParameters, this is not a canonical representation.
| .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)) : null; | ||
| } | ||
|
|
||
| public static String getCanonicalPlanName(Map<String, String> repositoryParameters) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cannot be a static method since you need access to the canonical keys set
| Repository repository = getRepository(respositoryId); | ||
| return repository.importArtefact(context, artefact.getRepositoryParameters()); | ||
| ImportResult importResult = repository.importArtefact(context, artefact.getRepositoryParameters()); | ||
| importResult.setCanonicalPlanName(getCanonicalPlanName(artefact.getRepositoryParameters())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cannot be a static call, you have the repository instance right above.
No description provided.