Class UpdateManager

java.lang.Object
com.ultikits.ultitools.manager.UpdateManager

@Internal public class UpdateManager extends Object
Manages version checking and update notifications for UltiTools-API and modules. Checks once at startup, stores results for later querying by commands and listeners.

As of 6.3.0 (Phase 19, D19-032):

  • The check stops when UltiTools disables. stop() is the first step of UltiTools#onDisable: it cancels the task if it has not started, and the running check looks at the stop flag before each lookup and before logging its result, so a server stopped while the check is in flight makes no further lookup and logs nothing at INFO or above. Anything thrown after the flag is set -- typically the closed plugin JAR, zip file closed, while a class is loaded -- is logged at FINE. The disable does not wait for a lookup in progress: an HTTP call cannot be interrupted, and waiting could hold the shutdown for up to the 30-second read timeout. This follows the panel-message shutdown fix (#621).
  • "Up to date" means every lookup confirmed it. A lookup that failed (unreachable catalogue, error status, unreadable body) is recorded in getUnconfirmed(), and the check then reports "Update check incomplete" naming what could not be confirmed, instead of "All plugins are up to date!".
Since:
6.2.0
  • Field Details

    • FRAMEWORK_NAME

      public static final String FRAMEWORK_NAME
      The name the framework's own lookup is reported under, in logs and in getUnconfirmed().
      See Also:
    • LOG_PREFIX

      private static final String LOG_PREFIX
      See Also:
    • logger

      private final Logger logger
    • stopped

      private volatile boolean stopped
      Set by stop(); read before each lookup and before the result is logged.
    • task

      private volatile org.bukkit.scheduler.BukkitTask task
      The scheduled check, cancelled by stop(); null until start(Plugin).
    • unconfirmed

      private volatile List<String> unconfirmed
      What the last completed check could not confirm, in lookup order: FRAMEWORK_NAME and module names. Replaced as a whole when a check completes.
    • frameworkUpdate

      private volatile UpdateInfo frameworkUpdate
    • moduleUpdates

      private final Map<String,UpdateInfo> moduleUpdates
    • notifiedPlayers

      private final Set<UUID> notifiedPlayers
      Players already notified about an available update, for the lifetime of this manager instance -- which is one server run: UltiTools.scheduleStartupMessages() builds a fresh UpdateManager exactly once per onEnable(), so a restart always starts from an empty set. Deliberately NOT @PlayerCache (#431): GEN-08/D-03 (plan 05-04) registered this field with PlayerCacheManager for quit-based sweeping to bound its size, but that made a quitting-and-rejoining player look never-notified within the SAME server run, breaking UpdateJoinListener's own documented promise of one notification per player per server session. The set's natural size bound is the number of distinct OP UUIDs that join this run, which does not grow on a repeat quit/rejoin of the same player -- there was no real unbounded-growth hazard here to trade the promise away for. Scoped to this field alone: the three other fields GEN-08/D-03 migrated onto PlayerCacheManager (in InMemoryNotificationService and InMemeryTeleportService) represent genuinely connection-scoped state and are untouched.
    • checkComplete

      private volatile boolean checkComplete
  • Constructor Details

    • UpdateManager

      public UpdateManager(Logger logger)
  • Method Details

    • start

      public void start(org.bukkit.plugin.Plugin plugin)
      Schedules the check on an asynchronous task, unless stop() was already called. Called once per onEnable, from the framework's start-up task.
      Parameters:
      plugin - the plugin that owns the task (UltiTools)
      Since:
      6.3.0
    • stop

      public void stop()
      Stops the check: called as the first step of UltiTools#onDisable. Cancels the task if it has not started; a check already running makes no further lookup, logs nothing at INFO or above from here on, and reports anything thrown at FINE. Does not wait for a lookup in progress. Safe to call more than once, and before start(Plugin).
      Since:
      6.3.0
    • isStopped

      public boolean isStopped()
      Returns:
      true once stop() has been called
      Since:
      6.3.0
    • getUnconfirmed

      public List<String> getUnconfirmed()
      What the last completed check could not confirm: FRAMEWORK_NAME when the framework lookup failed, and the name of each module whose lookup failed. Empty before a check completes and when every lookup established its answer.
      Returns:
      an unmodifiable list, never null
      Since:
      6.3.0
    • checkUpdatesSync

      public void checkUpdatesSync()
      Run update checks synchronously. Called from async context (the task start(Plugin) schedules). Returns at once, logging nothing, when stop() has been called.
    • checkFrameworkUpdate

      private void checkFrameworkUpdate(List<String> failed)
    • checkModuleUpdates

      private void checkModuleUpdates(List<String> failed)
    • recordFailedLookup

      private void recordFailedLookup(List<String> failed, String name, VersionLookup lookup)
      A lookup that answered but established nothing: the name joins the incomplete line, and the cause goes to FINE only, so a catalogue that cannot be reached produces one INFO line per start rather than one WARNING per module.
    • logThrown

      private void logThrown(String message)
      An exception from a lookup: a WARNING while UltiTools runs, as before 6.3.0; FINE once stop() has been called, because then it is the shutdown's doing (the closed plugin JAR), not a fault worth an operator's attention.
    • info

      private void info(String message)
      One INFO line of the result, unless stop() has been called: a disable that arrives while the result is being written silences the lines still to come.
    • logResults

      private void logResults(List<String> failed)
    • hasAnyUpdates

      public boolean hasAnyUpdates()
      Check if any updates (framework or modules) are available.
      Returns:
      true if any updates are available
    • isPlayerNotified

      public boolean isPlayerNotified(UUID uuid)
      Check if a player has already been notified about available updates.
      Parameters:
      uuid - the player's UUID
      Returns:
      true if the player has been notified
    • markPlayerNotified

      public void markPlayerNotified(UUID uuid)
      Mark a player as having been notified about available updates. The mark lives for this manager instance's lifetime (one server run) and is not cleared when the player quits (#431).
      Parameters:
      uuid - the player's UUID