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

Consolidating ClientService and js-ws and js-rpc integration #560

Merged
merged 27 commits into from
Oct 10, 2023

Conversation

tegefaulkes
Copy link
Contributor

@tegefaulkes tegefaulkes commented Sep 13, 2023

Description

In this PR we're consolidating the client service logic into a ClientService class that handles its life cycle.

Issues Fixed

Tasks

  • 1. Create a ClientService class within the client domain.
  • 2. Move RPC and WebsocketServer creation and life-cycle into ClientService.
  • 3. PolykeyAgent will be updated to use this.
  • 4. Tests will be updated to use this. Should reduce setup logic.
  • 5. Add PolykeyAgent.clientServiceHost, PolykeyAgent.clientServicePort, PolykeyAgent.agentServiceHost, PolykeyAgent.agentServicePort as getter property so that they can be used directly instead of referring to encapsulated objects for the host and port.

Final checklist

  • Domain specific tests
  • Full tests
  • Updated inline-comment documentation
  • Lint fixed
  • Squash and rebased
  • Sanity check the final build

@tegefaulkes tegefaulkes self-assigned this Sep 13, 2023
@ghost
Copy link

ghost commented Sep 13, 2023

👇 Click on the image for a new way to code review

Review these changes using an interactive CodeSee Map

Legend

CodeSee Map legend

@CMCDragonkai
Copy link
Member

CMCDragonkai commented Sep 26, 2023

I'm reassigning this to @amydevs and @addievo. You can take over this PR or join this PR for integrating js-ws and js-rpc.

Make sure to do a release before integrating here.

This PR could be rebased on top of #552 if #552 merges first.

If this merges first, then #552 can be rebased on top.

@CMCDragonkai
Copy link
Member

Remember to review #559.

However if this is consolidating, @tegefaulkes how come there isn't any deleted files in the diff right? I thought files would be moved from somewhere else.

@CMCDragonkai CMCDragonkai changed the title ClientService consolidation Consolidating ClientService and js-ws and js-rpc integration Sep 26, 2023
@tegefaulkes
Copy link
Contributor Author

Remember to review #559.

However if this is consolidating, @tegefaulkes how come there isn't any deleted files in the diff right? I thought files would be moved from somewhere else.

No deletions yet, it's mostly consolidating the client into a ClientService that handles all of the client stuff. So it was just adding that and modifying other places to use it. No deletions needed there.

However if we're using the js-rpc and js-ws libraries now then we need to remove the rpc and websocket domain and replace it with the libs.

@CMCDragonkai
Copy link
Member

flow of ClientService

@CMCDragonkai
Copy link
Member

@addievo add yourself to the constributors in package.json.

@CMCDragonkai
Copy link
Member

@amydevs make sure to push often here even for intermediate commits.

@amydevs
Copy link
Member

amydevs commented Sep 29, 2023

Client service will require an empty stream handler for the ClientServiceClient, as this behaviour is currently unexpected and will cause creation of unneeded resources. When we decide to add push notifs, etc. We can replace this with handlers for that.

@CMCDragonkai
Copy link
Member

Just immediately close the stream as soon as you get the event. For now server shouldn't be creating streams. But we will make use of this feature later in the future.

@CMCDragonkai
Copy link
Member

Has this been rebased on #560?

@amydevs amydevs force-pushed the feature-client-consolidation branch 2 times, most recently from f2064f5 to 883fbbf Compare October 4, 2023 04:42
@tegefaulkes tegefaulkes changed the base branch from feature-config-defaults to staging October 4, 2023 06:04
@CMCDragonkai
Copy link
Member

This is the main PR to work on now.

Goals:

  • Get js-ws and js-rpc fully integrated and tested
  • Fix up any tests that relate to using the client service and/or agent service
  • Make sure this is working with Polykey-CLI

I can see that there are branch conflicts in this PR... I thought this was rebased?

@CMCDragonkai
Copy link
Member

@amydevs please rebase this on top of staging too.

@tegefaulkes
Copy link
Contributor Author

It was rebased, but a linting commit in staging brought in a bunch of conflicts. They'll be mostly whitespace but git doesn't fully understand that.

@CMCDragonkai
Copy link
Member

It occurs to me that the serverManifest is a parameter of the NodeConnectionManager but the clientManifest the NodeConnection uses is hard coded. This may be something we'd want to make consistent.

Make them both hardcoded or both paramaterised but defaulted?

@tegefaulkes
Copy link
Contributor Author

Easiest way is to bind this back for the generator functions.

@CMCDragonkai
Copy link
Member

Did you make both clientManifest and serverManifest hardcoded?

src/PolykeyAgent.ts Outdated Show resolved Hide resolved
src/PolykeyClient.ts Outdated Show resolved Hide resolved
@CMCDragonkai
Copy link
Member

Easiest way is to bind this back for the generator functions.

I'm not sure this makes sense to me. I just asked chatgpt...

The constructor binding approach generally won't work if you define the async generator function as a class field, like handle = async *function () { }. Class fields are essentially syntactic sugar that allows you to declare and initialize instance properties directly within the class body. When you define a function as a class field, it gets attached to the instance, not the prototype. Therefore, binding it again inside the constructor doesn't work as expected, because the class field has already captured the instance context.

Here's an example to demonstrate:

class MyClass {
  constructor() {
    this.handle = this.handle.bind(this);  // This line is essentially a no-op
  }

  handle = async function*() {
    // `this` is already bound to the class instance because of the class field initialization
  }
}

In this case, the handle function is already bound to the instance of the class due to the class field definition. The constructor's explicit bind() becomes a no-op in this context because handle is already an instance method, not a prototype method. Therefore, binding it again in the constructor doesn't change the behavior of this within handle.

So, if you're using class fields to define your async generator function, you don't need to worry about binding this in the constructor—it's automatically bound to the instance of the class.

@CMCDragonkai
Copy link
Member

On second thought... chatgpt might be wrong here.

You are correct, and I apologize for the earlier error. The constructor binding is indeed effective when using class field syntax with async function* or regular functions. It's not a no-op in this case; it would bind this to the class instance.

When you define a method as a class field like handle = async function*() { }, it doesn't automatically bind this. The method is initialized with each new instance of the class, but its this context is determined by how it's invoked, just like any regular function.

Binding the function in the constructor would ensure that this is correctly set to the instance of the class. Here's an example:

class MyClass {
  constructor() {
    this.handle = this.handle.bind(this);
  }

  handle = async function*() {
    // `this` is now correctly bound to the class instance
  }
}

In this example, explicitly binding this.handle in the constructor ensures that it will always be bound to an instance of MyClass, regardless of how or where it is invoked. Thank you for bringing this to my attention, and I appreciate the opportunity to correct this information.

@tegefaulkes
Copy link
Contributor Author

I fixed that by doing the binding when registering the handler inside the RPCServer. Pretty much how it worked before but I only changed it back for the generators.

Fixed idGen usage in `PolykeyClient` and imports in `PolykeyAgent`
@tegefaulkes
Copy link
Contributor Author

ClientService still needs to be converted to StartStop rather than CreateDestroyStartStop. I'll make an issue in a moment.

@tegefaulkes
Copy link
Contributor Author

I'm skipping squashing here. This has been merged into and I don't want any potential problems.

@tegefaulkes
Copy link
Contributor Author

tegefaulkes commented Oct 10, 2023

Did you make both clientManifest and serverManifest hardcoded?

The clientManifest is hard coded inside the NodeConnection. The serverManifest is passed into the NCM prevent it from depending on everything during testing.

@tegefaulkes
Copy link
Contributor Author

New issue #565.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Consolidating client service logic and lifecycle
4 participants