Repository navigation
Give the result of an update from memory to its caller alone - #169
Merged
Merged
Conversation
The data updates specification says an update from memory reports nothing to the update complete callbacks, and either returns success or fails with an error that is passed to the caller rather than logged. That is data-updates.md lines 372 to 376 at 706de1f0, with lines 312 to 316 for a buffer passed in by a programmatic update from memory and lines 477 to 479 for errors. The errors table's row for data held in memory, line 510, gives the message "An error occurred when applying a data update to engine '<Engine type name>'." and the status AUTO_UPDATE_REFRESH_FAILED. These tests fail on the current code, which reports each update from memory to the callbacks, returns a failure status rather than raising, and logs the failure. New tests in test_datafile_update_http.py: - testAFailedRefreshRaisesAndIsNeitherReportedNorLogged, for a data file kept in memory, whose data goes back to what it was - testAFailedRefreshOfAFileDataFileRaisesAndIsNeitherReportedNorLogged, for a data file kept on disk - testAFailedTemporaryCopyFromMemoryRaisesAsAnyOtherError - testFailedCopyFromMemoryRaisesAnErrorNamingThePath - testNoTemporaryPathFromMemoryRaises Each failure is a DataUpdateException whose status is the failure's status, whose message is the message of its row of the errors table, and whose cause is the error that caused it. The data file is no longer marked as updating afterwards. The only entry logged is the attempt to refresh the engine, which is a message during operation and not an error. Existing tests changed, because each asserted the behavior the specification rules out: - testMemoryDataFileIsRefreshedFromTheBytes and testFileDataFileIsWrittenThenRefreshed asserted that a successful update from memory reported AUTO_UPDATE_SUCCESS to the callbacks. They now assert that nothing is reported and that only the attempt is logged. - testFailedRefreshIsReportedAndLogged asserted a returned AUTO_UPDATE_REFRESH_FAILED and a logged error. It is replaced by testAFailedRefreshRaisesAndIsNeitherReportedNorLogged. - testAFailedWriteFromMemoryEndsTheUpdate asserted a returned AUTO_UPDATE_NEW_FILE_CANT_RENAME that was also reported to the callbacks and logged. It now asserts the error raised, with nothing reported or logged. The update still ends without refreshing the engine. - testFailedCopyNamesThePath and testNoTemporaryPathIsReported asserted the logged message and the returned status through update_from_memory. They now make the same assertions through a check for an update, which still logs and reports, so that route stays covered, and the new tests above cover update_from_memory. - testACallbackErrorOnAnUpdateFromMemoryIsLoggedAndStopsTheCallbacks asserted that update_from_memory called the callbacks. It is replaced by testAnUpdateFromMemoryCallsNoCallback. Refs #149
update_from_memory reported its status to the update complete callbacks, returned a failure status, and logged the failure. The data updates specification says an update from memory reports nothing to onUpdateCallbacks and returns success or fails with an error, in data-updates.md lines 372 to 376 at 706de1f0, and that the error goes to the caller instead of being logged, in lines 312 to 316 and lines 477 to 479. update_from_memory now behaves as follows: - It reports nothing to the update complete callbacks on any path. - It returns AUTO_UPDATE_SUCCESS when the engine was refreshed. - It raises DataUpdateException when the refresh fails, with the message of the errors table's row for data held in memory, line 510, which is "An error occurred when applying a data update to engine '<Engine type name>'.", the status AUTO_UPDATE_REFRESH_FAILED, and the refresh error chained as its cause. Nothing is logged apart from the attempt to refresh the engine. The engine keeps the data it had, and a data file kept in memory gets its previous data back, as before. - It raises DataUpdateException when a data file kept on disk cannot be written, with the message and status the write failure already had, the error chained as its cause, and nothing logged. The engine is not refreshed, as before. A failed refresh of a data file kept on disk from update_from_memory now carries the row for data held in memory rather than the row for a refresh from the data file, because the data came from the caller. .NET's UpdateFromMemory does the same. DataUpdateException is a new class in datafile_update_service, named as .NET's is, with a status attribute. No public name is removed or renamed. The update lock and the updating flag are held and restored as before. The write helper now raises rather than logging, and the check for an update logs the failure itself, with the same message, level and status, and reports it to the callbacks as before. Update polling, the file system watcher and the programmatic check are otherwise unchanged. A data file that has been unregistered, because its engine was closed, still returns AUTO_UPDATE_NOT_NEEDED with nothing done. The specification gives an update from memory two results, success or an error, and does not describe an update from memory after the engine has been closed. The no configuration status in lines 338 to 339 and 372 to 375 is for a programmatic check, not for an update from memory. So the specification does not settle this case, and it is left as it was. The errors table's row for a failed write of data passed in from memory, line 511, is still not followed. That row is a warning, after which the engine is still refreshed. The engine of a data file kept on disk here refreshes by reading the file, so it cannot take data that was not written, and the update ends with an error instead. Refs #149
This was referenced Nov 15, 2026
Open
jwrosewell
marked this pull request as ready for review
November 15, 2026 04:32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An update from memory gave its result to the update complete callbacks as well as to its caller, returned a failure as a status, and logged it. It now reports nothing to the callbacks, returns
AUTO_UPDATE_SUCCESS, and raises a failure to its caller without logging it, as the data update specification says.Closes #149.
Problem
DataFileUpdateService.update_from_memory(datafile_update_service.pylines 310 to 363 at 28e5bf2c) passed its status to the update complete callbacks on both of its paths (self.__emit(status, data_file)), returnedAUTO_UPDATE_REFRESH_FAILEDor the status of a failed write rather than raising, and logged the failure through_refreshand_write_data_file(#149).What the specification says
data-updates.md lines 372 to 376 at 706de1f0:
Lines 477 to 479: "A programmatic check, the update on start-up and an update from memory pass the error to their caller instead of logging it."
What changed
All in
pipeline/fiftyone_pipeline_engines.cda98342, the tests, intests/test_datafile_update_http.py. New:testAFailedRefreshRaisesAndIsNeitherReportedNorLogged(a data file kept in memory keeps its old data),testAFailedRefreshOfAFileDataFileRaisesAndIsNeitherReportedNorLogged,testAFailedTemporaryCopyFromMemoryRaisesAsAnyOtherError,testFailedCopyFromMemoryRaisesAnErrorNamingThePath,testNoTemporaryPathFromMemoryRaisesandtestAnUpdateFromMemoryCallsNoCallback. Changed, as each asserted the old behaviour:testMemoryDataFileIsRefreshedFromTheBytesandtestFileDataFileIsWrittenThenRefreshednow expect no callback and only the "Attempting to refresh" log entry,testAFailedWriteFromMemoryEndsTheUpdateexpects an error with nothing reported or logged, the earliertestFailedRefreshIsReportedAndLoggedandtestACallbackErrorOnAnUpdateFromMemoryIsLoggedAndStopsTheCallbacksare replaced by the tests above, andtestFailedCopyNamesThePathandtestNoTemporaryPathIsReportednow run throughupdate_data_file, so the logging and reporting of the check route stay tested.502cadcb, the change. A new publicDataUpdateException(message, status)carries the failure's status, with the error that caused it chained.update_from_memoryreports nothing to the callbacks, returnsAUTO_UPDATE_SUCCESSonce the engine is refreshed, and raisesDataUpdateExceptionfor a failed refresh, with "An error occurred when applying a data update to engine ''." andAUTO_UPDATE_REFRESH_FAILED, and for a failed write of a data file kept on disk, with that write's message and status. Neither is logged. The engine keeps the data it had. The update lock and theupdatingflag work as before. On the check route a failed write is logged and reported exactly as before, through_log_failed_write.Before you upgrade
update_from_memoryno longer calls the update complete callbacks.DataUpdateException, whosestatusis the status it returned before (AUTO_UPDATE_REFRESH_FAILED,AUTO_UPDATE_NEW_FILE_CANT_RENAME,AUTO_UPDATE_TEMP_PATH_NOT_SETorAUTO_UPDATE_UNKNOWN_ERROR), and it is not logged. Code that checked the returned status for a failure catches the exception instead.AUTO_UPDATE_NOT_NEEDEDand does nothing.How it was verified
rc1190974) plus only a throwaway workflow. On Ubuntu and Windows the nine new and changed update from memory tests failed, "9 failed, 43 passed" intest_datafile_update_http.pyand "9 failed, 85 passed" across the engines tests, and the two check route tests passed.rc1190974, is green. Its ten Build and Test jobs, Python 3.10 to 3.14 on Ubuntu and Windows, each passed, withtest_datafile_update_http.pypassing in each. The 11Setting 'PullRequestSha'lines all name 502cadc, and Configure printed "Left out 5 macOS entries". macOS was left out of this draft's full build under the 9 November decision. The rc head is built with macOS before it merges into main.What it releases
fiftyone_pipeline_enginesand its dependants, which Monday's release plan releases already.What remains