Yukkuricraft / YakumoDash

Webtool for managing all Yukkuricraft software infrastructure
0 stars 0 forks source link

Reimplement Sockets With ngrx for Proper Reactive Cluster Component State #37

Open remiscarlet opened 1 month ago

remiscarlet commented 1 month ago

Rather than relying on long-running api request responses to update cluster/container state in the store, we should really have a separate socket connection that transmits all state information to Yakumo.

This would generally involve refactoring a lot of the current ngrx usage that only updates state based on aforementioned api calls.

Copypasting infodump from discord:

-- For thoughts on what might be a better way to implement sockets on yakumodash, I think rather than the components directly using data from the sockets service, the information passed through the socket connection should be populating the ngrx store (react store) with information that the UI components react to.

Generally speaking the information being passed through the socket should be cluster state information like "is the cluster up?" "What state is this container in?" "How many players are online on this server/proxy?" etc. That's all stateful information and in a properly architected frontend app, almost all of that "interesting state" should be stored in the "store". UI components should really just be reading state from the store and rendering accordingly.

You'll notice that with some of the components that were made earlier on while I was still learning, a lot of state information is being stored in the components themselves as observable subscriptions directly to the services themself. I think that's an antipattern for the whole data <-> render flow for modern webapps

-- The best example of what I'm describing above would be the whole backups components, store, and service files. The backups component, using "store actions", makes a service/api call which returns data that's saved into the store state, which then triggers a state change flow ("store effects") which the components are subscribed to and then render the backups list using the new store state data etc Remilia "Aqua" Scarlet — Today at 1:10 PM Here's a shitty diagram of what I mean by the backups stuff. I gloss over store "reducers" and "selectors" but that would happen at 3. and 4/component instantiation time respectively

So the sockets stuff would basically just replace "Backups Service" with "Sockets Service" Component: https://github.com/Yukkuricraft/YakumoDash/blob/main/src/app/components/backup-management/backup-management.component.ts Facade/Actions: https://github.com/Yukkuricraft/YakumoDash/blob/main/src/app/store/backups/backups.facade.ts Effects: https://github.com/Yukkuricraft/YakumoDash/blob/main/src/app/store/backups/backups.effects.ts Service: https://github.com/Yukkuricraft/YakumoDash/blob/main/src/app/services/backups/backups.service.ts

remiscarlet commented 1 month ago

To expand a bit further, in an ideal world state information would be populated in two ways using sockets:

  1. A client-side emitted "Refresh current state" event
    • This is a "pull" mechanism
    • This would get called at app instantiation and at appropriate times when the app wants a complete refresh of current state.
    • This might require an argument so we're refreshing specific clusters. "Refresh current state for env1" etc.
      • This might mean we need a prior "Get all existing envs" event to get a list of valid envs to refresh state for
  2. A server-side emitted "State change" event
    • This is a "push" mechanism
    • For an already instantiated app, this would be the primary way the app would update cluster/container/server state information.
    • Instead of relying on api responses from say "start the cluster", we would first send the "start the cluster" request which immediately returns a 200, then we'll receive a "state change" socket event once the cluster/containers have been started which will then update the frontend store state.