Consistent network rebooting using a controller and infinite channels
bk5115545 opened this issue · 7 comments
Describe the bug
I'm running with appliedenergistics2-forge-15.2.13
using the "channels": "infinite",
config option. This issue does not happen when only using an energy acceptor instead of a controller.
When there is a controller on my network, the network reboots every time a cable is added or removed. When there is not a controller on the network, there is no reboot.
I want to use a controller because it decreases the passive AE drain.
This screenshot is a small network that exhibits this issue. My real network is much more complex and part of a modpack but I reproduced this issue running only AE2. Additionally, my network does not reboot when I make changes without a controller so I think I've isolated the issue to be related to the controller.
This network reboot issue is causing issues for my friends and I because it resets UIs and stops general auto-crafting until the network reboots. We can mostly work around it by setting pathfindingStepsPerTick
to 128
however that causes some TPS lag in our world.
How to reproduce the bug
Create a network using infinite channels and add a controller. Add a cable. The network will reboot.
This issue is more obvious with larger networks. You can set pathfindingStepsPerTick
to 1
to simulate a 4x larger network than you build.
Expected behavior
The network should not reboot as it doesn't need to without the controller.
Additional details
Optionally, a config option to disable the increased AE drain on controller-less networks would also allow us to work around this issue.
Which minecraft version are you using?
1.20.1
On which mod loaders does it happen?
Forge
Crash log
Does not crash
This code is pretty good...
I believe I've isolated the issue to an assumption in https://github.com/AppliedEnergistics/Applied-Energistics-2/blob/main/src/main/java/appeng/me/service/PathingService.java#L117-L129 that assumes a controller means the network needs to be rebooted even when using infinite channels. A simple fix may be to add && this.channelMode != ChannelMode.INFINITE
.
I need to investigate the differences between PathingCalculation
vs calculateAdHocChannels
to determine if there may be performance issues with leveraging calculateAdHocChannels
for massive networks (like maybe PathingCalculation
happens iteratively per pathfindingStepsPerTick
and calculateAdHocChannels
doesn't.
On one hand, my hack most does what I want - the network goes through a 1-tick reboot which is too fast for client UIs to flicker or interrupt users. Additionally, this actually improves performance for infinite-channel networks that use a controller as well however the power usage ends up being very incorrect.
I traced this down to differences in the calculation methodology between the AdHoc process versus PathingCalculation
:
[23:03:39] [Server thread/WARN] [ap.me.se.PathingService/]: PATHING: Channels by blocks: 3550; channels in use: 80
[23:03:39] [Server thread/WARN] [ap.me.se.PathingService/]: POWER: 90.0
[23:03:55] [Server thread/WARN] [ap.me.se.PathingService/]: ADHOC: Channels by blocks: 11520; channels in use: 80
[23:03:55] [Server thread/WARN] [ap.me.se.PathingService/]: POWER: 90.0
PathingCalculation uses way less power because it simply allocates fewer channels; this is because Adhoc networks essentially allocate every channel to every block for the purposes of power consumption. I guess the best thing I could hope for would be an optimization to the pathfinder to not need to walk the network twice
Well PathingCalculation always needs to walk something twice but I think there's an optimization that can be made by allowing intermediate pathing work to be persisted and then PathingService can delegate add/removeNode to this persistent calculation.
When adding a node, there's no need to reboot the grid if a channel can be found - if one can't be found; attempt a reboot exactly once (same behavior as today)
When removing a node, there is potential that a reboot would enable additional connections to be allocated a channel but we can only get in this edge case if we first added too many channels and failed to find a route during the fallback reboot. In this case, we only need to reboot on removeNode if not all connections have a channel. There's future optimization work here that can be done by remembering channel routes/paths that are overcommitted (have a higher desired vs available channel number) and then only rebooting if removing a node routes over that path.
I am worried about the memory consumption of this possible fix though; Java being Java and all. I might get more time to play around with this but who knows honestly. While this is a lot of effort to bring infinite-channel /w controller networks to be less annoying, it does optimize the core grid add/remove for all types of networks and so might just be worth it
I think I made some progress here: #8279
I also think i can actually use optimistic updates to 1/2 the amount of grid traversal that PathingCalculation
needs to do when calculating channels. Still walks the same number of nodes in the case of not having enough channels but would only walk once instead of twice for networks that have enough free channels. Since the majority of networks have enough channels, I think this will be a significant performance bump to PathingCalculation
as well