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

refactor(core): Generalize binary data manager interface (no-changelog) #7164

Merged
merged 115 commits into from
Sep 22, 2023

Conversation

ivov
Copy link
Contributor

@ivov ivov commented Sep 13, 2023

Depends on: #7092 | Story: PAY-768

This PR:

  • Generalizes the IBinaryDataManager interface.
  • Adjusts Filesystem.ts to satisfy the interface.
  • Sets up an S3 client stub to be filled in in the next PR.
  • Turns BinaryDataManager into an injectable service.
  • Adjusts the config schema and adds new validators.

Note that the PR looks large but all the main changes are in packages/core/src/binaryData.

Out of scope:

  • BinaryDataManager (now BinaryDataService) and Filesystem.ts (now fs.client.ts) were slightly refactored for maintainability, but fully overhauling them is not the focus of this PR, which is meant to clear the way for the S3 implementation. Future improvements for these two should include setting up a backwards-compatible dir structure that makes it easier to locate binary data files to delete, removing duplication, simplifying cloning methods, using integers for binary data size instead of prettyBytes(), writing tests for existing binary data logic, etc.

@n8n-assistant n8n-assistant bot added core Enhancement outside /nodes-base and /editor-ui n8n team Authored by the n8n team labels Sep 13, 2023
@github-actions
Copy link
Contributor

Great PR! Please pay attention to the following items before merging:

Files matching packages/**:

  • If fixing bug, added test to cover scenario.
  • If addressing forum or Github issue, added link to description.

Files matching packages/**/*.ts:

  • Added unit tests to cover new or updated functionality.

Files matching packages/nodes-base/nodes/**:

  • Added workflow tests for nodes if possible.

Make sure to check off this list before asking for review.

@@ -900,9 +893,9 @@ export const schema = {
},
},

binaryDataManager: {
binaryDataService: {
availableModes: {
Copy link
Member

Choose a reason for hiding this comment

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

Renaming this is a breaking change, and should be documented in BREAKING-CHANGES.md

Copy link
Contributor Author

@ivov ivov Sep 21, 2023

Choose a reason for hiding this comment

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

Reverted: 605d02b

Maybe in future we can bundle all changes like this together, to minimize annoyance for users.

Copy link
Member

Choose a reason for hiding this comment

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

if we are reverting, can we revert all of the renaming, and not just the config? either that, or we don't revert and list this as a breaking change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think there is benefit in a temporary middle ground. Preexisting code uses "manager" for both binary data manager and its modes, so it's rather confusing and inconsistent. With this division into service and managers, the distinction is clearer, and the inconsistency is reduced to only this handful of entrypoint config spots where the renaming would cause a breaking change. So on balance the bulk of code becomes clearer.

krynble
krynble previously approved these changes Sep 22, 2023
Copy link
Contributor

@krynble krynble left a comment

Choose a reason for hiding this comment

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

LGTM

if (this.availableModes.includes('filesystem') && config.mode === 'filesystem') {
this.managers.filesystem = new FileSystemManager(config.localStoragePath);

await this.managers.filesystem.init();
Copy link
Contributor

Choose a reason for hiding this comment

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

Loading this conditionally means that if we switch back to default after using filesystem for a while means we cannot read previous executions anymore. Given we want to allow people to switch freely between modes, I think we always have to init all managers based on the available modes rather than the default one, wdyt?

Screenshot 2023-09-20 at 16 21 16

Copy link
Contributor Author

@ivov ivov Sep 22, 2023

Choose a reason for hiding this comment

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

Thank you, please see 20d5ea7.

import type { BinaryData } from './types';

const EXECUTION_ID_EXTRACTOR =
/^(\w+)(?:[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12})$/;
Copy link
Contributor

Choose a reason for hiding this comment

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

For learning only, this regular expression can be simplified to use lazy operator instead of lookahead, which is a bit more expensive. Feel free to ignore.

Suggested change
/^(\w+)(?:[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12})$/;
/^(.*?)([0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12})$/;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Love it, I didn't know this. Since there are no tests and we will be refactoring this in future, for now I'll keep it as it was beforehand.

* - `filesystem` (on disk)
* - `object` (S3)
*/
export const BINARY_DATA_MODES = ['default', 'filesystem', 'object'] as const;
Copy link
Contributor

Choose a reason for hiding this comment

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

The name object makes me think of the native js Object and I have a tendency to think this is somewhat related to a hash map.

What about just calling it S3 since this is what it does reflect?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please see 0cdfb79

@cypress
Copy link

cypress bot commented Sep 22, 2023

1 flaky test on run #2252 ↗︎

0 235 3 0 Flakiness 1

Details:

🌳 pay-768-generalize-binary-data-manager-interface 🖥️ browsers:node18.12.0-chr...
Project: n8n Commit: d27e4c4467
Status: Passed Duration: 08:33 💡
Started: Sep 22, 2023 2:42 PM Ended: Sep 22, 2023 2:51 PM
Flakiness  cypress/e2e/24-ndv-paired-item.cy.ts • 1 flaky test

View Output Video

Test Artifacts
NDV > resolves expression with default item when input node is not parent, while still pairing items Output Screenshots Video

This comment has been generated by cypress-bot as a result of this project's GitHub integration settings.

@github-actions
Copy link
Contributor

✅ All Cypress E2E specs passed

@krynble
Copy link
Contributor

krynble commented Sep 22, 2023

Small note: for some reason I'm getting this on my terminal:

Press "o" to open in Browser.
InvalidBinaryDataManagerError: No binary data manager found
InvalidBinaryDataManagerError: No binary data manager found
InvalidBinaryDataManagerError: No binary data manager found

When viewing executions. Any ideas @ivov ?

Edit: feel free to ignore, I can no longer reproduce this issue. I guess I was running an old build.

`LogCatch` was merged into master at a different file: `/packages/core/binaryData/index.ts`, which is now at `BinaryData.service.ts`
@ivov
Copy link
Contributor Author

ivov commented Sep 22, 2023

Small note: for some reason I'm getting this on my terminal:

Press "o" to open in Browser.
InvalidBinaryDataManagerError: No binary data manager found
InvalidBinaryDataManagerError: No binary data manager found
InvalidBinaryDataManagerError: No binary data manager found

When viewing executions. Any ideas @ivov ?

Unable to reproduce, messaging you for more details.

krynble
krynble previously approved these changes Sep 22, 2023
@github-actions
Copy link
Contributor

✅ All Cypress E2E specs passed

Copy link
Contributor

@krynble krynble left a comment

Choose a reason for hiding this comment

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

LGTM

@github-actions
Copy link
Contributor

✅ All Cypress E2E specs passed

@ivov ivov merged commit 6d6e248 into master Sep 22, 2023
52 of 53 checks passed
@ivov ivov deleted the pay-768-generalize-binary-data-manager-interface branch September 22, 2023 15:22
ivov added a commit that referenced this pull request Sep 25, 2023
…ager interface (no-changelog) (#7195)

Depends on: #7164 | Story:
[PAY-838](https://linear.app/n8n/issue/PAY-838/introduce-object-store-service-for-binary-data)

This PR removes `storeMetadata` and `getSize` from the binary data
manager interface, as these are specific to filesystem mode. Also this
disambiguates identifiers:

```
binaryDataId
filesystem:289b4aac51e-dac6-4167-b793-6d5c415e2b47 {mode}:{fileId}

fileId - FS
289b4aac51e-dac6-4167-b793-6d5c415e2b47 {executionId}{uuid}

fileId - S3
/workflows/{workflowId}/executions/{executionId}/binary_data/b4aac51e-dac6-4167-b793-6d5c415e2b47
```

Note: The object store changes originally in this PR were extracted out
into the final PR.

---------

Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
@janober
Copy link
Member

janober commented Sep 28, 2023

Got released with n8n@1.9.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Enhancement outside /nodes-base and /editor-ui n8n team Authored by the n8n team Released
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants