-
Notifications
You must be signed in to change notification settings - Fork 3
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
Port manager #42
Port manager #42
Conversation
constants/ports.ts
Outdated
export const MAX_PORT_NUMBER = 65535; | ||
|
||
// TODO: What's a good port for the port manager? | ||
export const PORT_MANAGER_SERVER_PORT = 12345; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe 8080? That's a classic one. Maybe we could also make it configurable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
8080 is good. Making it configurable could be tricky because the UI needs to know where to look for it
utils/PortManagerServer.ts
Outdated
this.app.use(express.json()); | ||
this.app.use(cors()); | ||
this.setupRoutes(); | ||
this.server = this.app.listen(PORT_MANAGER_SERVER_PORT, () => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may want to pull some of the logic from here that forces the rest of the process to wait to make sure that the server started up successfully. It makes it easier to catch + log errors in the calling function
this.app.post('/close', this.closeServer); | ||
} | ||
|
||
setPort(instanceId: string, port: number) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this protect against initializing duplicate instanceId's?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setPort
is only called by assignPortToServer
, which does protect against duplicates
constants/ports.ts
Outdated
export const MIN_PORT_NUMBER = 1024; | ||
export const MAX_PORT_NUMBER = 65535; | ||
|
||
// TODO: What's a good port for the port manager? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lingering todo (unless you still plan to revisit this)
lang/en.lyaml
Outdated
@@ -136,6 +136,12 @@ en: | |||
processFieldsJs: | |||
converting: 'Converting "{{ src }}" to "{{ dest }}".' | |||
converted: 'Finished converting "{{ src }}" to "{{ dest }}".' | |||
utils: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm realizing we're going to hit some merge conflicts with all of the WIP PR's and my translations spike PR
lang/en.lyaml
Outdated
started: "PortManagerServer running on port {{ port }}" | ||
setPort: "Server with instanceId {{ instanceId }} assigned to port {{ port }}" | ||
deletedPort: "Server with instanceId {{ instanceId }} unassigned from port {{ port }}" | ||
close: "PortManagerServer shutting down." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should refer to this differently in logs. End users probably don't need to know about portManagerServer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, though these are all debug logs so theoretically end users wouldn't be seeing them. Seemed helpful if anyone was ever debugging something related to this or the inner workings became relevant to their workflow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok, I was thinking that they were standard logs. That makes sense 👌
utils/detectPort.ts
Outdated
|
||
export function detectPort(port?: number | null): Promise<number> { | ||
if (port && (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER)) { | ||
throw new Error('Port must be between 1024 and 65535'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should put this copy in the lang file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah good call, I guess I'll hold off on that until the lang stuff is merged
|
||
const i18nKey = 'utils.PortManagerServer'; | ||
|
||
class PortManagerServer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a blocker - I wonder if we should even bother having a models/
folder in this repo. I think we have a few other classes in here that also aren't in that folder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah 🤷 . Was left over from cli-lib but definitely don't think we need to make the distinction. I'm down to remove in the future
}); | ||
}; | ||
|
||
getServerPortByInstanceId = (req: Request, res: Response): void => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the return on this be Promise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't thinks so, this isn't async. Express knows how to handle it as is
@@ -0,0 +1,90 @@ | |||
import net, { AddressInfo } from 'net'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to include the copyright info in here per the license: https://github.com/node-modules/detect-port/blob/master/LICENSE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call. I could have sworn I had already done this
I'm ok with it being a fast-follow, but we should probably also get some unit tests in place for these new utils. This will be a good start to us getting in the habit of making sure everything new is tested. |
lang/en.json
Outdated
}, | ||
"detectPort": { | ||
"errors": { | ||
"invalidPort": "Port must be between 1024 and 65535" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be useful to have these min and max numbers be dynamic so changing the variable values will automatically change the message here.
lang/en.json
Outdated
"duplicateInstance": "Failed to start PortManagerServer. An instance of PortManagerServer is already running.", | ||
"404": "Could not find a server with instanceId {{ instanceId }}", | ||
"409": "Failed to assign port. Server with instanceId {{ instanceId }} is already running on port {{ port }}", | ||
"400": "Invalid port requested. Port must be between 1024 and 65535." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same dynamic suggestion here
Description and Context
See https://git.hubteam.com/HubSpot/hubspot-cli-issues/issues/462
This PR is a proof of concept for the Port Manager Server, which seeks to address the above issue by creating a separate service that the CLI interfaces to assign ports to dev servers, assuring that no port conflicts happen when running multiple servers. The Port Manager Server also provides an API for the UIExtensionManager (and future extension managers) to interface with from the UI, telling it which ports to look for dev servers on.
The bulk of the functionality of this PR is in the following three files
utils/PortManagerServer.ts
- Class that handles spinning the the express serverutils/detectPort.ts
- Logic for assigning ports based on what's availablelib/portManager.ts
- set of functions that the CLI (and other repos, potentially) can use to easily interact with the port manager.Related port manager PRs:
HubSpot/hubspot-cli#936
https://git.hubteam.com/HubSpot/ui-extensibility/pull/1566
TODO
Who to Notify
@brandenrodgers @kemmerle