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

A way to instantiate a resource that must be a singleton inside a dev environment #18264

Open
4 tasks done
sapphi-red opened this issue Oct 3, 2024 · 5 comments
Open
4 tasks done
Labels
enhancement New feature or request feat: environment API Vite Environment API

Comments

@sapphi-red
Copy link
Member

sapphi-red commented Oct 3, 2024

Description

I noticed that we have a same problem with #12734 if a different server (e.g. miniflare) is used in DevEnvironment.
When restarting the server (by editing the config or pressing r + enter), the next instantiation happens before devEnv::close is called. In the end the server crashes with address already in use error caused by the different server.
#16358 (comment)

configureServer has the same problem: #17285

Suggested solution

Made two PRs with different approach.

Alternative

No response

Additional context

No response

Validations

@sapphi-red sapphi-red added enhancement New feature or request feat: environment API Vite Environment API labels Oct 3, 2024
@hi-ogawa
Copy link
Collaborator

hi-ogawa commented Oct 8, 2024

From a quick look, listen seems easier to understand. To utilize isRestart, wouldn't it still require keeping things on globalThis because environments and plugins are re-instantiated? I'm not sure what's intended, but I can only think of something fairly ugly:

class MyEnv extends DevEnvironment {
  init({ isRestart }) {
    if (isRestart) {
      // recreate it here
      globalThis.__something.close()
      globalThis.__something = new SomeResource(someOptions)
  
      // or maybe resource can restart itself
      // globalThis.__something.restart(someOptions)

    } else {
      globalThis.__something = new SomeResource(someOptions)
    }
  }

  // then what to do here?
  // close() {}
}

For listen, I guess I can just put it under instance:

class MyEnv extends DevEnvironment {
  public resource;
  listen() {
    this.resource = new SomeResource(someOptions)
  }
  close() {
    this.resource.close();
  }
}

If I have listen and also know that init works unintuitively, I think I would move all "init" logic to listen. Would it limit anything for environment usages? If not, then is it possible to rename current init as _initInternal and use proposed listen as new init?

@sapphi-red
Copy link
Member Author

Oh, that's right. @patak-dev Did you have something in mind that resolve this problem for the isRestart flag?

@patak-dev
Copy link
Member

I wasn't thinking on a isRestart flag, but instead in having a environment.restart() function like we have for the server.restart(). Instead of creating a new environment, if there was an environment with the same name, then that instance will get a environment.restart(newConfig) and it could decide to keep the state it doesn't want to re-create. This may be quite hard to implement (if it is possible), so if listen() gives us a way to somehow avoid the need to destroy and re-create the world on restart for certain environments, then that sounds good to me. I wonder if we still should have some concept like environment.init(prevEnvironmentInstance) for environments to adopt whatever they need from the instance that is about to get destroyed.

@sapphi-red
Copy link
Member Author

I see. Yeah, I think we need a way to take over the previous state (e.g. using the same port and not finding a random port again).

@sapphi-red
Copy link
Member Author

I made a PR that implements environment.restart (#18353). Also changed #18263 to make it possible to get the previous env instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request feat: environment API Vite Environment API
Projects
None yet
Development

No branches or pull requests

3 participants