tyvm Tens & Rill.
It's actually really interesting that this is happening in the Sov system - I knew it was happening on rare occasion (about 1 in 1000) in the Siege system, but not in Sov de-levelling.
The only thing they have in common is that both de-levelling systems rely on a WHILE code loop, to process the de-levelling iteratively. We don't like WHILE loops in general, they have built-in problems, but they're a shortcut to using a full on event queueing system. I believe these are the only two WHILE loops in the codebase.
I suspect now that the culprit is the loop itself, where - if the whole server is under some DB pressure at runtime - the actual underlying data de-level doesn't get committed by SQL before the next iteration runs. hence the dupes.
If this is the case, this is potentially relatively easily fixed in a couple of different ways:
a) One way would be simply to instruct the WHILE loop to WAIT for a millisecond or two for the DB commit to the update before resuming. This would be slower (by a few milliseconds per loop), but would have the advantage of making sure that separate processes operating at precisely the same time - ie two or more sieges hitting at the same time within milliseconds of each other (which would be a very rare occurrence) b) The more accurate way would be to pull all the data about the "thing-to-be-de-levelled" into a local table variable in the Stored Procedure, regardless of whose operations were de-levelling it (ie multiple simultaneous sieges), then run all the operations locally at runtime in the SP, and then perform the de-levelling.
a) would be faster to implement and would be absolutely fine in 99.999% of circumstances, albeit locking a Stored Proc (and therefore a CPU thread) for a few more milliseconds than necessary b) would be a better fix, but would require quite a major rework of the "event processor" to recognise simultaneous de-levelling events initiated by multiple players occurring at *precisely* the same time, and process them together
I'll have a poke around in the code and see what's what; we also have historic data, so I can check and see whether two or more sieges have ever hit the same town at the same millisecond. If not, Option a) would work fine.
Thanks v much for making the connection between siege de-levelling and sov de-levelling - this has really helped me narrow down what's happening in the code!
Best,
SC
|