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

add installation truncation #192

Closed
wants to merge 134 commits into from

Conversation

feng-j678
Copy link
Contributor

@feng-j678 feng-j678 commented Jun 6, 2023

What is in this PR:
[X] Compressed assessment and installation patches
[X] Add tombstone record for compressed assessment per classifications.
[X] Add tombstone record for compressed installation.
[X] Add error details for compressed assessment.
[X] Add error details for compressed installation.
[X] set status as warning when compression applied.
[X] Clean up multi-line formatting.
[X] Test assessment and installation compression.
[X] Unit test coverage...
[x] delay truncation logic - add condition to check current time vs truncation timestamp if 60 secs have passed. when timestamp is below 60 secs, truncation logic will not apply during application process unless the terminal state has reached (success or error)


image
image
image
image

@codecov
Copy link

codecov bot commented Jun 6, 2023

Codecov Report

Merging #192 (424953d) into master (b50ef62) will increase coverage by 0.72%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master     #192      +/-   ##
==========================================
+ Coverage   90.39%   91.11%   +0.72%     
==========================================
  Files          90       90              
  Lines       14810    15941    +1131     
==========================================
+ Hits        13387    14525    +1138     
+ Misses       1423     1416       -7     
Flag Coverage Δ
python27 91.11% <100.00%> (+0.72%) ⬆️
python39 91.11% <100.00%> (+0.72%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
src/core/src/CoreMain.py 97.00% <100.00%> (+0.03%) ⬆️
src/core/src/bootstrap/Constants.py 98.71% <100.00%> (+0.05%) ⬆️
.../core/src/core_logic/ConfigurePatchingProcessor.py 94.84% <100.00%> (ø)
src/core/src/service_interfaces/StatusHandler.py 97.10% <100.00%> (+2.29%) ⬆️
src/core/tests/Test_CoreMain.py 99.92% <100.00%> (+0.04%) ⬆️
src/core/tests/Test_StatusHandler.py 99.88% <100.00%> (+0.10%) ⬆️

... and 1 file with indirect coverage changes

@feng-j678 feng-j678 force-pushed the user/johnfeng/add_installation_truncation branch from a3e0028 to 6d6f8fa Compare June 6, 2023 20:47
@feng-j678 feng-j678 force-pushed the user/johnfeng/add_installation_truncation branch from fe0f93f to f34c848 Compare August 29, 2023 19:01
@kjohn-msft
Copy link
Collaborator

@feng-j678 @rane-rajasi
Where is the conditional writes for performance tracked (write truncated status only once in x minutes)?
I don't see it in the PR description as tracked, and its not superficially clear that it's done.

@feng-j678
Copy link
Contributor Author

@feng-j678 @rane-rajasi Where is the conditional writes for performance tracked (write truncated status only once in x minutes)? I don't see it in the PR description as tracked, and its not superficially clear that it's done.

checker condition code added.

Copy link
Contributor

@rane-rajasi rane-rajasi left a comment

Choose a reason for hiding this comment

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

Did a very short pass, so this is not my final review for the current iteration.

Please add a brief description on what this PR is trying to achieve with some details. For eg: how is it trying to truncate, when does it truncate, why is the skip by seconds logic added, etc.,

@@ -101,6 +101,7 @@ def __init__(self, argv):
patch_installer.mark_installation_completed()
overall_patch_installation_operation_successful = True
self.update_patch_substatus_if_pending(patch_operation_requested, overall_patch_installation_operation_successful, patch_assessment_successful, configure_patching_successful, status_handler, composite_logger)
status_handler.log_truncated_packages()

Copy link
Contributor

Choose a reason for hiding this comment

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

Note: to be raised and discussed between @kjohn-msft, @feng-j678 and me

self.env_layer.file_system.write_with_retry_using_temp_file(self.complete_status_file_path, '[{0}]'.format(status_file_payload_json_dumps), mode='w+')

if Constants.StatusTruncationConfig.TURN_ON_TRUNCATION:
status_file_payload_json_dumps = self.__check_file_byte_size_for_truncation(status_file_payload_json_dumps)
Copy link
Contributor

Choose a reason for hiding this comment

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

The function name __check_file_byte_size_for_truncation() indicates it only checks the size, however this function not only checks size but also applies truncation if needed. Please rename the function to convey it's actions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

method name updated -. __check_status_file_size_perform_truncation_if_needed(). at this point the method name is getting longer like paragraph. looking for suggestion for shorter name. done

curr_timestamp = datetime.datetime.now()
return (curr_timestamp - track_truncation_timestamp).total_seconds() >= Constants.StatusTruncationConfig.SKIP_TRUNCATION_LOGIC_IN_X_SEC

def __set_force_truncation_true(self, status):
Copy link
Contributor

Choose a reason for hiding this comment

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

Rename to: __set_force_truncation_true_for_terminal_status()

This function is being called for all status values (Success, Error, Transitioning...), so it's important for the name to reflect the functionality

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

# Write agent status file
self.env_layer.file_system.write_with_retry_using_temp_file(self.status_file_path, '[{0}]'.format(json.dumps(complete_status_payload)), mode='w+')
if Constants.StatusTruncationConfig.TURN_ON_TRUNCATION:
truncated_status_file_json_dumps = self.__validate_status_file_for_truncation(status_file_payload_json_dumps)
Copy link
Contributor

Choose a reason for hiding this comment

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

__validate_status_file_for_truncation(): Is this just validating or is this performing truncation also? The name indicates it will simply validate

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done, see above comment

track_truncation_timestamp = datetime.datetime.now()

curr_timestamp = datetime.datetime.now()
return (curr_timestamp - track_truncation_timestamp).total_seconds() >= Constants.StatusTruncationConfig.SKIP_TRUNCATION_LOGIC_IN_X_SEC
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this skip truncation by secs added?

Also, the function name again does not clearly state what is happening within

Copy link
Contributor Author

Choose a reason for hiding this comment

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

add description, done.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not a blocker for the first validation round: But the description, within function or in PR, does not explain "why" this skip truncation logic is added.

Also, based on my assumption, of this logic, truncation should be skipped if the remaining time (i.e. current - track_tuncation) <= Constants.StatusTruncationConfig.SKIP_TRUNCATION_LOGIC_IN_X_SEC. Is this correct?

So the last statement should be:
return (curr_timestamp - track_truncation_timestamp).total_seconds() > Constants.StatusTruncationConfig.SKIP_TRUNCATION_LOGIC_IN_X_SEC

@rane-rajasi
Copy link
Contributor

Did a very short pass, so this is not my final review for the current iteration.

Please add a brief description on what this PR is trying to achieve with some details. For eg: how is it trying to truncate, when does it truncate, why is the skip by seconds logic added, etc.,

PR description can be made further descriptive:
for eg: The last point states there is a delay added in the truncation logic, but does not explain why the delay is introduced.

PR description should briefly state the issue we see today and our solution. See the previous comment on "Please add a brief description on what this PR is trying to achieve with some details. For eg: how is it trying to truncate, when does it truncate, why is the skip by seconds logic added, etc.,"

if status_file_size_in_bytes > self.__internal_file_capacity: # perform truncation complete_status_file byte size > 126kb
is_delay_truncation_by_x_sec = self.__check_truncation_time_passed_by_x_sec(self.__track_truncation_timestamp)

if is_delay_truncation_by_x_sec or self.__force_truncation_on:
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this condition read as:
If there is no delay required for truncation OR force truncation is on?

If so, the check should be:
if not is_delay_truncation_by_x_sec or self.__force_truncation_on:

This is why a description conveying the intent/ desired functionality of the code is important, either in function description or PR description

Also, the function and variable names need to be modified to reflect the intent, but leaving that for the next review

@feng-j678 feng-j678 force-pushed the user/johnfeng/add_installation_truncation branch from 5882b0d to 2521e8a Compare October 19, 2023 23:31
# Map['classification', count]
for package in packages_removed_from_assessment:
classifications = package['classifications'][0]
assessment_tombstone_map[classifications] = assessment_tombstone_map.get(classifications, 0) + 1
Copy link
Contributor

Choose a reason for hiding this comment

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

assessment_tombstone_map.get()

Wouldn't this throw an error on empty list?

Copy link
Contributor Author

@feng-j678 feng-j678 Oct 20, 2023

Choose a reason for hiding this comment

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

done. if that's the case, this code is unreachable:

line 1000
if len(packages_removed_from_assessment) > 0:
self.__assessment_packages_removed = packages_removed_from_assessment
assessment_tombstone_records = self.__create_assessment_tombstone_list(self.__assessment_packages_removed)
packages_retained_in_assessment.extend(assessment_tombstone_records)

assessment_tombstone_map[classifications] = assessment_tombstone_map.get(classifications, 0) + 1

# Add assessment tombstone record per classifications except unclassified
for tombstone_classification, tombstone_package_count in assessment_tombstone_map.items():
Copy link
Contributor

Choose a reason for hiding this comment

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

Where are things being written into assessment_tombstone_map?
Line 1188 initializes it to an empty value, line 1194 does a .get() on an empty list. Don't see any values being set in it

Copy link
Contributor Author

@feng-j678 feng-j678 Oct 20, 2023

Choose a reason for hiding this comment

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

done. if that's the case, this code is unreachable:

line 1000
if len(packages_removed_from_assessment) > 0:
self.__assessment_packages_removed = packages_removed_from_assessment
assessment_tombstone_records = self.__create_assessment_tombstone_list(self.__assessment_packages_removed)
packages_retained_in_assessment.extend(assessment_tombstone_records)

# Add assessment tombstone record per classifications except unclassified
for tombstone_classification, tombstone_package_count in assessment_tombstone_map.items():
if not tombstone_classification == Constants.PackageClassification.UNCLASSIFIED:
tombstone_record_list.append(self.__create_assessment_tombstone(tombstone_package_count, tombstone_classification))
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we adding 1 tombstone record for every classification type? I don't remember what was discussed on this previously but I have doubts on the usefulness of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done. yes, this was a one of the requirements.

Copy link
Contributor

@rane-rajasi rane-rajasi left a comment

Choose a reason for hiding this comment

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

Left some comments inline, but my overall review is:

  • Need a description of the current functionality and why each change is being introduced (i.e. what is the desired outcome)
  • The changes are there but due to the enormity of this PR and the number of things being added, it is difficult to ensure that all intended changes are implemented and everything works together as desired.
  • we should consider splitting this PR into parts for easier review.

The parts can be: (1 PR for each)

  1. Basic truncation of assessment and installation patches (Simply removing additional patches with No tombstone or error details). This will also include re-composing the status file post truncation. TBD if this can be further split
  2. Adding tombstone records on truncation
  3. Adding error details on truncation
  4. Adding delay on truncation
  5. Any other changes not covered so far

@feng-j678 feng-j678 force-pushed the user/johnfeng/add_installation_truncation branch from 108eb27 to 2d411e1 Compare October 20, 2023 07:12
@feng-j678 feng-j678 closed this Mar 20, 2024
@feng-j678 feng-j678 deleted the user/johnfeng/add_installation_truncation branch September 9, 2024 23:03
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.

3 participants