Enum Class LiveTableMonitor

java.lang.Object
java.lang.Enum<LiveTableMonitor>
com.illumon.iris.db.tables.live.LiveTableMonitor
All Implemented Interfaces:
com.fishlib.base.log.LogOutputAppendable, LiveTableRegistrar, NotificationQueue, NotificationQueue.Dependency, Serializable, Comparable<LiveTableMonitor>, java.lang.constant.Constable

This class contains a thread which periodically updates a set of monitored LiveTables at a specified target cycle time. The target cycle time can be configured to reduce or increase the refresh rate of the monitored tables.

This class can be configured via the following Configuration property

  • LiveTableMonitor.targetcycletime (optional) - The default target cycle time in ms (1000 if not defined)
  • Enum Constant Details

  • Method Details

    • values

      public static LiveTableMonitor[] values()
      Returns an array containing the constants of this enum class, in the order they are declared.
      Returns:
      an array containing the constants of this enum class, in the order they are declared
    • valueOf

      public static LiveTableMonitor valueOf(String name)
      Returns the enum constant of this class with the specified name. The string must match exactly an identifier used to declare an enum constant in this class. (Extraneous whitespace characters are not permitted.)
      Parameters:
      name - the name of the enum constant to be returned.
      Returns:
      the enum constant with the specified name
      Throws:
      IllegalArgumentException - if this enum class has no constant with the specified name
      NullPointerException - if the argument is null
    • setDefaultRegistrar

      public static void setDefaultRegistrar(@NotNull LiveTableRegistrar newDefault)
      Set the LiveTableRegistrar to redirect to when the LTM has been disabled.
      Parameters:
      newDefault - the new LiveTableRegistrar
    • setDefaultNotificationQueue

      public static void setDefaultNotificationQueue(@NotNull NotificationQueue newDefault)
      Set the NotificationQueue to redirect to when the LTM has been disabled.
      Parameters:
      newDefault - the new NotificationQueue
    • append

      public com.fishlib.base.log.LogOutput append(@NotNull com.fishlib.base.log.LogOutput logOutput)
      Specified by:
      append in interface com.fishlib.base.log.LogOutputAppendable
    • toString

      public String toString()
      Overrides:
      toString in class Enum<LiveTableMonitor>
    • getUpdateThreads

      public int getUpdateThreads()
      Retrieve the number of update threads.

      The LiveTableMonitor has a configurable number of update processing threads. The number of threads is exposed in your method to enable you to partition a query based on the number of threads.

      Returns:
      the number of update threads configured.
    • sharedLock

      public AwareFunctionalLock sharedLock()

      Get the shared lock for this LiveTableMonitor.

      Using this lock will prevent refresh processing from proceeding concurrently, but will allow other read-only processing to proceed.

      The shared lock implementation is expected to support reentrance.

      This lock does not support Lock.newCondition(). Use the exclusive lock if you need to wait on events that are driven by refresh processing.

      Returns:
      The shared lock for this LiveTableMonitor
    • exclusiveLock

      public AwareFunctionalLock exclusiveLock()

      Get the exclusive lock for this LiveTableMonitor.

      Using this lock will prevent refresh or read-only processing from proceeding concurrently.

      The exclusive lock implementation is expected to support reentrance.

      Note that using the exclusive lock while the shared lock is held by the current thread will result in exceptions, as lock upgrade is not supported.

      This lock does support Lock.newCondition().

      Returns:
      The exclusive lock for this LiveTableMonitor
    • lock

      @Deprecated public final void lock()
      Deprecated.
      Prefer {exclusiveLock()}.lock().
    • lockInterruptibly

      @Deprecated public final void lockInterruptibly() throws InterruptedException
      Deprecated.
      Prefer {exclusiveLock()}.lockInterruptibly().
      Throws:
      InterruptedException
    • tryLock

      @Deprecated public final boolean tryLock()
      Deprecated.
      Prefer {exclusiveLock()}.tryLock().
    • tryLock

      @Deprecated public final boolean tryLock(long time, @NotNull TimeUnit unit) throws InterruptedException
      Deprecated.
      Prefer {exclusiveLock()}.tryLock().
      Throws:
      InterruptedException
    • unlock

      @Deprecated public final void unlock()
      Deprecated.
      Prefer {exclusiveLock()}.unlock().
    • newCondition

      @Deprecated public final Condition newCondition()
      Deprecated.
      Prefer {exclusiveLock()}.newCondition().
    • isLockedByCurrentThread

      @Deprecated public final boolean isLockedByCurrentThread()
      Test if this thread holds the lock (exclusively).
      Returns:
      Whether the current thread holds the lock exclusively
    • doLocked

      @Deprecated public final <T> T doLocked(@NotNull Supplier<T> r)
      Safely execute the supplied code while holding the lock.
      Parameters:
      r - the stuff to run
      Returns:
      the result of the stuff to run
    • doLockedInterruptible

      @Deprecated public final <T> T doLockedInterruptible(@NotNull Supplier<T> r) throws InterruptedException
      Safely execute the supplied code while holding the lock. Lock acquisition may be interrupted.
      Parameters:
      r - the stuff to run
      Returns:
      the result of the stuff to run
      Throws:
      InterruptedException - if the thread was interrupted attempting to acquire the lock
    • doLocked

      @Deprecated public final void doLocked(@NotNull com.fishlib.base.Procedure.Nullary r)
      Safely execute the supplied code while holding the lock.
      Parameters:
      r - the stuff to run
    • computeLocked

      @Deprecated public final <R> R computeLocked(@NotNull com.fishlib.base.Function.Nullary<R> r)
      Safely execute the supplied function while holding the lock.
      Parameters:
      r - the function to run
      Returns:
      the return value of the function
    • doLockedInterruptible

      @Deprecated public final void doLockedInterruptible(@NotNull com.fishlib.base.Procedure.Nullary r) throws InterruptedException
      Safely execute the supplied code while holding the lock.
      Parameters:
      r - the stuff to run
      Throws:
      InterruptedException
    • doLockedThrowing

      @Deprecated public final <T extends Exception> void doLockedThrowing(@NotNull com.fishlib.base.Procedure.ThrowingNullary<T> r) throws T
      Safely execute the supplied code while holding the lock.
      Parameters:
      r - the stuff to run
      Throws:
      T - exception of type T
    • isRefreshThread

      public boolean isRefreshThread()
      Test if this thread is part of our refresh thread executor service.
      Returns:
      whether this is one of our refresh threads.
    • checkInitiateTableOperation

      public void checkInitiateTableOperation()

      If we are establishing a new table operation, on a refreshing table without the LiveTableMonitor lock; then we are likely committing a grievous error, but one that will only occasionally result in us getting the wrong answer or if we are lucky an assertion. This method is called from various query operations that should not be established without the LTM lock.

      The refresh thread pool threads are allowed to instantiate operations, even though that thread does not have the lock; because they are protected by the main refresh thread and dependency tracking.

      If you are sure that you know what you are doing better than the query engine, you may call setCheckTableOperations(boolean) to set a thread local variable bypassing this check.

    • setCheckTableOperations

      public boolean setCheckTableOperations(boolean value)
      If you know that the table operations you are performing are indeed safe, then call this method with false to disable table operation checking. Conversely, if you want to enforce checking even if the configuration disagrees; call it with true.
      Parameters:
      value - the new value of check table operations
      Returns:
      the old value of check table operations
    • doUnchecked

      public <T> T doUnchecked(Supplier<T> supplier)
      Execute the supplied code while table operations are unchecked.
      Parameters:
      supplier - the function to run
      Returns:
      the result of supplier
    • doUnchecked

      public void doUnchecked(Runnable runnable)
      Execute the supplied code while table operations are unchecked.
      Parameters:
      runnable - the function to run
    • getCheckTableOperations

      public boolean getCheckTableOperations()
      Should this thread check table operations?
      Returns:
      if we should check table operations.
    • setTargetCycleTime

      public void setTargetCycleTime(long cycleTime)

      Set the target clock time between refresh cycles.

      Can be reset to default via resetCycleTime()

      Parameters:
      cycleTime - The target time between refreshes in milliseconds
      ImplNote:
      Any cycle time < 0 will be clamped to 0.
    • getTargetCycleTime

      public long getTargetCycleTime()
      Get the target period between refresh cycles.
      Returns:
      The current minimum cycle time
    • resetCycleTime

      public void resetCycleTime()
      Resets the refresh cycle time to the default target configured via the LiveTableMonitor.targetcycletime property.
      ImplNote:
      If the LiveTableMonitor.targetcycletime property is not set, this value defaults to 1000ms.
    • enableUnitTestMode

      public void enableUnitTestMode()

      Enable unit test mode.

      In this mode calls to addTable(LiveTable) will only mark tables as refreshing. Additionally start() may not be called.

    • disable

      public void disable()
      Disable execution of the LTM. This can only be done before start() has been called and will prevent the update thread and refresh threads from starting.
    • setWatchDogMillis

      public void setWatchDogMillis(int watchDogMillis)
      Enable the loop watchdog with the specified timeout. A value of 0 disables the watchdog.
      Parameters:
      watchDogMillis - The time in milliseconds to set the watchdog, or 0 to disable.
      ImplNote:
      Any timeout < 0 will be clamped to 0.
    • getWatchDogMillis

      public int getWatchDogMillis()
      Get the current watchdog timeout value.
      Returns:
      The current timeout for the watchdog, 0 for disabled
    • setWatchDogTimeoutProcedure

      public void setWatchDogTimeoutProcedure(LongConsumer procedure)
      Set the procedure to be called when the watchdog times out.
      Parameters:
      procedure - The procedure to call
    • requestSignal

      public void requestSignal(Condition liveTableMonitorCondition)
    • start

      public void start()
      Start the table refresh thread.
      ImplNote:
      Must not be in unit test mode.
    • addTable

      public void addTable(@NotNull LiveTable table)
      Add a table to the list of tables to refresh and mark it as refreshing if it was a DynamicNode.
      Specified by:
      addTable in interface LiveTableRegistrar
      Parameters:
      table - The table to be added to the refresh list
      ImplNote:
      This will do nothing in unit test mode other than mark the table as refreshing.
    • removeTable

      public void removeTable(@NotNull LiveTable liveTable)
      Description copied from interface: LiveTableRegistrar
      Remove a table from this registrar.
      Specified by:
      removeTable in interface LiveTableRegistrar
      Parameters:
      liveTable - The table to remove
    • removeTables

      public void removeTables(@NotNull Collection<LiveTable> tablesToRemove)
      Remove a collection of tables from the list of refreshing tables.
      Specified by:
      removeTables in interface LiveTableRegistrar
      Parameters:
      tablesToRemove - The tables to remove from the list of refreshing tables
      ImplNote:
      This will not set the tables as non-refreshing.
    • addNotification

      public void addNotification(@NotNull NotificationQueue.Notification notification)
      Enqueue a notification to be flushed according to its priority. Non-terminal notifications should only be enqueued during the updating phase of a cycle. That is, they should be enqueued from a LiveTable.refresh() or subsequent notification delivery.
      Specified by:
      addNotification in interface NotificationQueue
      Parameters:
      notification - The notification to enqueue
      See Also:
    • maybeAddNotification

      public boolean maybeAddNotification(@NotNull NotificationQueue.Notification notification, long deliveryStep)
      Description copied from interface: NotificationQueue
      Add a notification for this NotificationQueue to deliver (by invoking its run() method), iff the delivery step is the current step and the update cycle for that step is still in process. This is only supported for non-terminal notifications.
      Specified by:
      maybeAddNotification in interface NotificationQueue
      Parameters:
      notification - The notification to add
      deliveryStep - The step to deliver this notification on
    • satisfied

      public boolean satisfied(long step)
      Description copied from interface: NotificationQueue.Dependency
      Is this ancestor satisfied? Note that this method must be safe to call on any thread.
      Specified by:
      satisfied in interface NotificationQueue.Dependency
      Parameters:
      step - The step for which we are testing satisfaction
      Returns:
      Whether the dependency is satisfied on step (and will not fire subsequent notifications)
    • addNotifications

      public void addNotifications(@NotNull Collection<? extends NotificationQueue.Notification> notifications)
      Enqueue a collection of notifications to be flushed.
      Specified by:
      addNotifications in interface NotificationQueue
      Parameters:
      notifications - The notification to enqueue
      See Also:
    • maybeRefreshTable

      public void maybeRefreshTable(@NotNull LiveTable liveTable, boolean onlyIfHaveLock)
      Acquire the exclusive lock if necessary and do a refresh of liveTable on this thread if it is registered with this LTM.
      Specified by:
      maybeRefreshTable in interface LiveTableRegistrar
      Parameters:
      liveTable - The LiveTable that we would like to refresh
      onlyIfHaveLock - If true, check that the lock is held first and do nothing if it is not
    • requestRefresh

      public void requestRefresh(@NotNull LiveTable liveTable)

      Request a refresh for a single live table, which must already be registered with this LiveTableMonitor.

      The update will occur on the LTM thread, but will not necessarily wait for the next scheduled cycle.

      Specified by:
      requestRefresh in interface LiveTableRegistrar
      Parameters:
      liveTable - The live table to refresh
    • resetForUnitTests

      @TestUseOnly public void resetForUnitTests()
      Clear all monitored tables and enqueued notifications to support unit-tests.
    • resetForUnitTests

      @TestUseOnly public void resetForUnitTests(boolean randomizedNotifications, int seed, int maxRandomizedThreadCount, int notificationStartDelay, int notificationAdditionDelay)
    • startCycleForUnitTests

      @TestUseOnly public void startCycleForUnitTests()
      Begin the next update cycle while in unit-test mode. Note that this happens on a simulated LTM refresh thread, rather than this thread.
    • startCycleForUnitTests

      @TestUseOnly public void startCycleForUnitTests(boolean rootsSatisfied)
      Begin the next update cycle while in unit-test mode. Note that this happens on a simulated LTM refresh thread, rather than this thread.
      Parameters:
      rootsSatisfied - if true, then the roots will be marked as satisfied, if false; then you must manually call rootRefreshCompleteForUnitTests()
    • rootRefreshCompleteForUnitTests

      @TestUseOnly public void rootRefreshCompleteForUnitTests()
      Mark the root tables satisfied within a unit test.
    • completeCycleForUnitTests

      @TestUseOnly public void completeCycleForUnitTests()
      Do the second half of the update cycle, including flushing notifications, and completing the LogicalClock update cycle. Note that this happens on a simulated LTM refresh thread, rather than this thread.
    • runWithinUnitTestCycle

      @TestUseOnly public <T extends Exception> void runWithinUnitTestCycle(FunctionalInterfaces.ThrowingRunnable<T> runnable) throws T
      Execute the given runnable wrapped with startCycleForUnitTests() and completeCycleForUnitTests(). Note that the runnable is run on the current thread.
      Parameters:
      runnable - the runnable to execute.
      Throws:
      T extends Exception
    • refreshLiveTableForUnitTests

      @TestUseOnly public void refreshLiveTableForUnitTests(@NotNull LiveTable liveTable)
      Refresh a LiveTable on a simulated LTM refresh thread, rather than this thread.
      Parameters:
      liveTable - The LiveTable to refresh
    • flushOneNotificationForUnitTests

      @TestUseOnly public boolean flushOneNotificationForUnitTests()
      Flush a single notification from the LTM queue. Note that this happens on a simulated LTM refresh thread, rather than this thread.
      Returns:
      whether a notification was found in the queue
    • flushOneNotificationForUnitTestsInternal

      @TestUseOnly public boolean flushOneNotificationForUnitTestsInternal()
    • flushAllNormalNotificationsForUnitTests

      @TestUseOnly public void flushAllNormalNotificationsForUnitTests()
      Flush all the normal notifications from the LTM queue. Note that the flushing happens on a simulated LTM refresh thread, rather than this thread.
    • flushAllNormalNotificationsForUnitTests

      @TestUseOnly public Runnable flushAllNormalNotificationsForUnitTests(@NotNull BooleanSupplier done, long timeoutMillis)
      Flush all the normal notifications from the LTM queue, continuing until done returns true. Note that the flushing happens on a simulated LTM refresh thread, rather than this thread.
      Parameters:
      done - Function to determine when we can stop waiting for new notifications
      Returns:
      A Runnable that may be used to wait for the concurrent flush job to complete
    • wakeRefreshThreadForUnitTests

      @TestUseOnly public void wakeRefreshThreadForUnitTests()
      If the refresh thread is waiting in flushNormalNotificationsAndCompleteCycle() or flushAllNormalNotificationsForUnitTests(BooleanSupplier, long), wake it up.
    • logDependencies

      public com.fishlib.io.log.LogEntry logDependencies(Object identity)