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

Fix startup race condition #3367

Merged
merged 10 commits into from
May 22, 2024
Merged

Fix startup race condition #3367

merged 10 commits into from
May 22, 2024

Conversation

analogic
Copy link
Collaborator

@analogic analogic commented May 21, 2024

Fixes #3366

Changes proposed in this pull request:

  • making endpoint.bind() to async and awaiting in server.js

Checklist:

  • docs updated
  • tests updated
  • Changes updated

@msimerson
Copy link
Member

It looks like you also need to await here

@analogic
Copy link
Collaborator Author

PR tested on multiple instances, seems OK

2024-05-21 20:25:39.085531500  [NOTICE] [-] [server] Listening on [::0]:25
2024-05-21 20:25:39.085777500  [NOTICE] [-] [server] Switching from current gid: 0
2024-05-21 20:25:39.086551500  [NOTICE] [-] [server] New gid: 8
2024-05-21 20:25:39.086589500  [NOTICE] [-] [server] Switching from current uid: 0
2024-05-21 20:25:39.087241500  [NOTICE] [-] [server] New uid: 88

Copy link
Member

@msimerson msimerson left a comment

Choose a reason for hiding this comment

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

LGTM.

I'd like to see one more change. Now that bind is async, I think we should be using fs/promises instead of sync calls:

diff --git a/endpoint.js b/endpoint.js
index 8154aef1..8f8e959a 100644
--- a/endpoint.js
+++ b/endpoint.js
@@ -1,7 +1,7 @@
 'use strict';
 // Socket address parser/formatter and server binding helper
 
-const fs = require('node:fs');
+const fs = require('node:fs/promises');
 const sockaddr = require('sockaddr');
 
 module.exports = function endpoint (addr, defaultPort) {

Since fs.exists has been deprecated for years, switch it to use fs.access or fs.stat before the await fs.unlink(path);

@msimerson
Copy link
Member

or ignore errors when the file doesn't exist:

await fs.rm(this.path, { force: true });

endpoint.js Outdated
opts.host = this.host;
opts.port = this.port;
}
server.listen(opts, done);

return await new Promise((resolve, reject) => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return await new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {

There's no need to await here.

@analogic
Copy link
Collaborator Author

When I "grep node:fs" I didn't find many "promises" so I assumed it would be better not to change. I chose "rm" for simplicity...

@msimerson msimerson merged commit c4ee966 into haraka:master May 22, 2024
13 checks passed
@msimerson
Copy link
Member

Thanks! Great job on the diagnosis and the fix.

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.

Race condition error: listen EACCES: permission denied ::0:25
2 participants