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

Adding a shutdown method to the AttachmentsFileManager #1428

Merged
merged 3 commits into from
Feb 12, 2025

Conversation

berhalak
Copy link
Contributor

@berhalak berhalak commented Feb 6, 2025

Context

During ActiveDoc shutdown process the AttachmentsFileManager's internal loop wasn't interrupted. This prevented server to shutdown gracefully.

Proposed solution

The manager class is now closed properly during ActiveDoc shutdown process. This still can be improved by implementing:

  • Proper close method for AttachmentsStoreProviders (currently it is dead code)
  • Propagating the AbortSignal to the External/Internal store providers that should abort the upload process

Has this been tested?

  • 👍 yes, I added tests to the test suite

Copy link
Member

@paulfitz paulfitz left a comment

Choose a reason for hiding this comment

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

Thanks for working on this @berhalak !

@@ -2170,6 +2170,9 @@ export class ActiveDoc extends EventEmitter {
};

try {
await safeCallAndWait('attachmentFileManager',
Copy link
Member

Choose a reason for hiding this comment

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

Is this not a little too early? The doc isn't yet marked as "muted" and disconnected from clients, so we could get parallel activity happening on the doc during this call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved it after webhooks shutdown.

@@ -106,6 +110,15 @@ export class AttachmentFileManager {
this._docPoolId = _docInfo ? getDocPoolIdFromDocInfo(_docInfo) : null;
}

public async shutdown(): Promise<void> {
if (this._loopAbort.aborted) {
throw new Error("shutdown already in progress");
Copy link
Member

Choose a reason for hiding this comment

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

This could be fine, or it could just skip to awaiting _transferJob? But I expect there's a deliberate reason for throwing an error here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I didn't want to allow calling this method twice. The abort signal is triggered 3 lines below.

app/server/lib/AttachmentFileManager.ts Outdated Show resolved Hide resolved
@paulfitz
Copy link
Member

paulfitz commented Feb 6, 2025

There are a lot of TypeError: this._loopAbort.throwIfAborted is not a function failures in CI.

@berhalak berhalak requested a review from paulfitz February 6, 2025 17:16
Comment on lines 449 to 451
if (this._loopAbort.aborted) {
throw new Error("AttachmentFileManager was shut down");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the thinking behind specifically erroring in this method, and not others? (E.g _storeFileInLocalStorage).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nothing special. I just thought that the external storage is likely to be the problem, not the internal or test.
Long story:
I actually first prepared a full solution here, fix the close method on providers (by calling it during shutdown), added signal for each upload (with some tricks, to abort readable streams, or pipes) and so on. But then I realized that it is too hard to test and to review. So I remove 99% of the code, and just left the simple method that should abort the loop.

Copy link
Contributor

@Spoffy Spoffy Feb 7, 2025

Choose a reason for hiding this comment

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

Re-reading this bit of the code, I'd guess the internal storage would have been the issue due to the DocStorage being shutdown and closing the DB connection. I think remote uploads would be fine, as the stores aren't tied to ActiveDoc for their connections .

I think you've guarded against the internal storage / DB access being a problem with the changes to ActiveDoc (as ActiveDoc awaits shutdown for this before closing DocStorage).

I'd be inclined to remove this - I'm not sure it's actually protecting against anything now, and might cause more errors (as I think the transfer would succeed without this guard in place).

Copy link
Contributor

@Spoffy Spoffy left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Member

@paulfitz paulfitz left a comment

Choose a reason for hiding this comment

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

Thanks @berhalak

@berhalak berhalak merged commit 86caf39 into main Feb 12, 2025
12 checks passed
@berhalak berhalak deleted the jareks/attachments-shutdown branch February 12, 2025 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants