Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-121586

Watchdog thread kills the server if average tick time is larger than max-tick-time/(15*20) ms for too long

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Resolution: Fixed
    • Affects Version/s: Minecraft 1.12.2
    • Fix Version/s: Minecraft 1.13-pre6
    • Labels:
      None
    • Confirmation Status:
      Unconfirmed

      Description

      This IS the same issue as the one described in MC-63590, but that issue is already closed because it "works as intended". The error message given clearly says it's not intended.

      I noticed the issue many times when working on my mod, and then I actually found the problem in code when trying to find the root cause of issue in other mod.

      I will just copy the explanation I game in this issue, where I originally found the cause: https://github.com/asiekierka/FoamFix/issues/40#issuecomment-320440131.

      The relevant decompiled code:

              while (this.serverRunning) {
                  long k = getCurrentTimeMillis();
                  long j = k - this.currentTime;
                  if (j > 2000L && this.currentTime - this.timeOfLastWarning >= 15000L) {
                      LOG.warn("Can\'t keep up! Did the system time change, or is the server overloaded? Running {}ms behind, skipping {} tick(s)", new Object[] {Long.valueOf(j), Long.valueOf(j / 50L)});
                      j = 2000L;
                      this.timeOfLastWarning = this.currentTime;
                  }
                  if (j < 0L) {
                      LOG.warn("Time ran backwards! Did the system time change?");
                      j = 0L;
                  }
                  i += j;
                  this.currentTime = k;
                  if (this.worlds[0].areAllPlayersAsleep()) {
                      this.tick();
                      i = 0L;
                  } else {
                      while (i > 50L) {
                          i -= 50L;
                          this.tick();
                      }
                  }
                  Thread.sleep(Math.max(1L, 50L - i));
                  this.serverIsRunning = true;
              }
      

      If the server tick time is more than 50ms on average for a longer amount of time, you get the "Can't keep up" messages. But it also means that this loop attempts to "fix" the issue by running many ticks at once before the message appears:

      while (i > 50L) {
          i -= 50L;
          this.tick();
      }
      

      The message is shown only if the server is 2000 or more ms behind (40 or more ticks) and it's been more than 15 seconds since mast message.

      But if the server is consistently lagging behind, then while the server attempts to run many ticks at once, it will get even more behind. If in that time it gets more than 60 seconds behind, which happens if it's already close to the 15 seconds behind and just about to show the next message, and the average tick time is >= 200ms (60000 / (15seconds*20TPS).

      So the watchdog thread will kill the server if your average tick time is greater than 200ms (or in general timeout/(15*20))

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                Barteks2x Bartosz Skrzypczak
              • Votes:
                5 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: