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

Improve the /download endpoint #311

Merged
merged 21 commits into from
Feb 26, 2024
Merged

Improve the /download endpoint #311

merged 21 commits into from
Feb 26, 2024

Conversation

dabico
Copy link
Member

@dabico dabico commented Feb 26, 2024

What started as a need for a simple change quickly escalated into a complete refactoring once a plethora of hidden issues was discovered. Here's what this PR includes:

  • The supported export formats now have their own enum ExportFormat;
  • The endpoint has been broken up into smaller, more readable steps;
  • The entity manager cache is periodically cleared to allow for more efficient GC;
  • The JsonGenerator is now periodically flushed during writes;
  • JsonFactory instances are now obtained from a dedicated converter;
  • Generated datasets are now always compressed;
  • Fixed incorrect request parameters included in JSON and XML exports;
  • Rename ExportConfig to JacksonConfig;
  • Added HateoasConfig for creating link builder beans;
  • HATEOAS link builders are now non-component classes.

From now on, this enum will be used to indicate supported export formats
within the platform. Each export format is denoted by the name of its
extension. At the same time, it is also associated with a media type,
which is indicated when streaming data to the client.
Aptly named `StringToExportFormatConverter`, it will be implicitly used
by the controller in mapping the `String` path variable to an
`ExportFormat` value.
Aptly named `ExportFormatToJsonFactoryConverter`, its use is not
immediately apparent. We will use it in the `download` route to generate
a factory based on the specified `ExportFormat`.
This would lead to redundant search parameter information being included
in the exports. This is no longer the case, and the only internally used
convenience getters are no longer generated in Jackson-produced exports.
This will realistically only impact fields with a `length`/`size`
attribute. While only `String` fields are affected at the moment,
this will also extend to list fields once we extend search to
plural parameters.
This contains too many changes to be split into smaller, consecutive
commits, so I will group them all into a larger commit. Why was this
change even made in the first place? Originally, I intended to add
the new `ExportFormat` and call it a day, but I noticed that there
were some memory allocation issues in the download that were caused
by:

1) Not using a `@PersistenceContext` entity manager
2) Not clearing the entity manager cache on a regular basis

With both changes, the memory issues have been addressed. After that,
my goal was only to improve the readability of the overall code. The
new code did see the removal of the `exportFormats` bean, as well as
changes to the `DownloadLinkBuilder`. Another change is that CSV
column values will now always be quoted.
Currently only provides a means for hiding the thrown exception for the
`CheckedRunnable`, and converting it to a regular `Runnable`. This will
be useful in code that depends on non-throwing lambdas.
The advantage of this new class is that it accepts an arbitrary number
of `Runnable` instances to execute when a specified counter condition
is met. This makes the code more reusable overall.

The reason this was done was to allow periodic flushes of the
`JsonGenerator`. Although I'm not 100% sure if this improves the
performance, we will revert it's flushing if it is determined to
be of no use.

This change was also the reason we introduced the `CheckedRunnable`
and its `IOException`-specialized counterpart.
@dabico dabico merged commit 839275e into master Feb 26, 2024
5 checks passed
@dabico dabico deleted the enhancement/download branch February 26, 2024 14:20
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.

1 participant