Fabric API

Fabric API

106M Downloads

Using Transfer API comparator calculator crashes the game

Juuxel opened this issue ยท 3 comments

commented
  • My BE's SingleVariantStorage<FluidVariant> has a markDirty call in onFinalCommit. From what I can see, this is standard.
  • When a transfer is made, markDirty calls World.updateComparators.
  • The same BE's block uses StorageUtil.calculateComparatorOutput(storage, null) to calculate the comparator output based on the aforementioned storage. World.updateComparators then calls this method (indirectly).
  • This opens another outer transaction while the transfer tx is still going on, and crashes: https://gist.github.com/Juuxel/b40ce8baf93e30865ab8ea18394b33cc

Note: Transaction.getCurrentUnsafe does not work either because it can't be used in a close callback (which onFinalCommit is)

commented

When I mentioned this during the original development,
the suggested solution was to mark your block internally as being dirty then do the real markDirty() on its next tick:
#1356 (comment)

The other way to do it would be move the --depth so that depth = -1 (no associated transaction)


during after close callbacks but this would likely play badly with other features?
It could also potentially lead to recursive calls seeing incomplete/old/wrong state?

commented

the suggested solution was to mark your block internally as being dirty then do the real markDirty() on its next tick

I had forgotten about this, but this might indeed be the best solution. I wouldn't be against a fabric API helper for this. Maybe just a simple public static void doLater(Runnable runnable) // do something at the end of the current server tick.

Allowing outer close callbacks to open transactions will probably complicate the implementations of non-trivial inventories even more.

commented

Fixed in 1.19 with #2139.