Enum LiveTableMonitor
- All Implemented Interfaces:
com.fishlib.base.log.LogOutputAppendable,LiveTableRegistrar,NotificationQueue,NotificationQueue.Dependency,Serializable,Comparable<LiveTableMonitor>,java.lang.constant.Constable
public enum LiveTableMonitor extends Enum<LiveTableMonitor> implements LiveTableRegistrar, NotificationQueue, NotificationQueue.Dependency
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)
-
Nested Class Summary
Nested classes/interfaces inherited from interface com.illumon.iris.db.tables.live.NotificationQueue
NotificationQueue.Dependency, NotificationQueue.IndexUpdateNotification, NotificationQueue.Notification -
Enum Constant Summary
Enum Constants Enum Constant Description DEFAULT -
Method Summary
Modifier and Type Method Description voidaddNotification(NotificationQueue.Notification notification)Enqueue a notification to be flushed according to its priority.voidaddNotifications(Collection<? extends NotificationQueue.Notification> notifications)Enqueue a collection of notifications to be flushed.voidaddTable(LiveTable table)Add a table to the list of tables to refresh and mark it asrefreshingif it was aDynamicNode.com.fishlib.base.log.LogOutputappend(com.fishlib.base.log.LogOutput logOutput)voidcheckInitiateTableOperation()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.voidcompleteCycleForUnitTests()Do the second half of the update cycle, including flushing notifications, and completing theLogicalClockupdate cycle.<R> RcomputeLocked(com.fishlib.base.Function.Nullary<R> r)voiddoLocked(com.fishlib.base.Procedure.Nullary r)<T> TdoLocked(Supplier<T> r)voiddoLockedInterruptible(com.fishlib.base.Procedure.Nullary r)<T> TdoLockedInterruptible(Supplier<T> r)<T extends Exception>
voiddoLockedThrowing(com.fishlib.base.Procedure.ThrowingNullary<T> r)Deprecated.voiddoUnchecked(Runnable runnable)Execute the supplied code while table operations are unchecked.<T> TdoUnchecked(Supplier<T> supplier)Execute the supplied code while table operations are unchecked.voidenableUnitTestMode()Enable unit test mode.AwareFunctionalLockexclusiveLock()Get the exclusive lock for thisLiveTableMonitor.voidflushAllNormalNotificationsForUnitTests()Flush all the normal notifications from the LTM queue.RunnableflushAllNormalNotificationsForUnitTests(BooleanSupplier done, long timeoutMillis)Flush all the normal notifications from the LTM queue, continuing untildonereturnstrue.booleanflushOneNotificationForUnitTests()Flush a single notification from the LTM queue.booleanflushOneNotificationForUnitTestsInternal()booleangetCheckTableOperations()Should this thread check table operations?longgetTargetCycleTime()Get the target period between refresh cycles.intgetUpdateThreads()Retrieve the number of update threads.intgetWatchDogMillis()Get the current watchdogtimeoutvalue.booleanisLockedByCurrentThread()Deprecated.booleanisRefreshThread()Test if this thread is part of our refresh thread executor service.voidlock()Deprecated.Prefer {exclusiveLock()}.lock().voidlockInterruptibly()Deprecated.Prefer {exclusiveLock()}.lockInterruptibly().com.fishlib.io.log.LogEntrylogDependencies(Object identity)booleanmaybeAddNotification(NotificationQueue.Notification notification, long deliveryStep)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.voidmaybeRefreshTable(LiveTable liveTable, boolean onlyIfHaveLock)Acquire the exclusive lock if necessary and do a refresh ofliveTableon this thread if it is registered with this LTM.ConditionnewCondition()Deprecated.Prefer {exclusiveLock()}.newCondition().voidrefreshLiveTableForUnitTests(LiveTable liveTable)Refresh aLiveTableon a simulated LTM refresh thread, rather than this thread.voidremoveTable(LiveTable liveTable)Remove a table from this registrar.voidremoveTables(Collection<LiveTable> tablesToRemove)Remove a collection of tables from the list of refreshing tables.voidrequestRefresh(LiveTable liveTable)Request a refresh for a singlelive table, which must already be registered with this LiveTableMonitor.voidrequestSignal(Condition liveTableMonitorCondition)voidresetCycleTime()Resets the refresh cycle time to the default target configured via the LiveTableMonitor.targetcycletime property.voidresetForUnitTests()Clear all monitored tables and enqueued notifications to supportunit-tests.voidresetForUnitTests(boolean randomizedNotifications, int seed, int maxRandomizedThreadCount, int notificationStartDelay, int notificationAdditionDelay)voidrootRefreshCompleteForUnitTests()Mark the root tables satisfied within a unit test.<T extends Exception>
voidrunWithinUnitTestCycle(FunctionalInterfaces.ThrowingRunnable<T> runnable)Execute the given runnable wrapped withstartCycleForUnitTests()andcompleteCycleForUnitTests().booleansatisfied(long step)Is this ancestor satisfied? Note that this method must be safe to call on any thread.booleansetCheckTableOperations(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.voidsetTargetCycleTime(long cycleTime)Set the target clock time between refresh cycles.voidsetWatchDogMillis(int watchDogMillis)Enable the loop watchdog with the specified timeout.voidsetWatchDogTimeoutProcedure(LongConsumer procedure)Set the procedure to be called when the watchdogtimes out.AwareFunctionalLocksharedLock()Get the shared lock for thisLiveTableMonitor.voidstart()Start the table refresh thread.voidstartCycleForUnitTests()Begin the nextupdate cyclewhile inunit-testmode.voidstartCycleForUnitTests(boolean rootsSatisfied)Begin the nextupdate cyclewhile inunit-testmode.StringtoString()booleantryLock()Deprecated.Prefer {exclusiveLock()}.tryLock().booleantryLock(long time, TimeUnit unit)Deprecated.Prefer {exclusiveLock()}.tryLock().voidunlock()Deprecated.Prefer {exclusiveLock()}.unlock().static LiveTableMonitorvalueOf(String name)Returns the enum constant of this type with the specified name.static LiveTableMonitor[]values()Returns an array containing the constants of this enum type, in the order they are declared.voidwakeRefreshThreadForUnitTests()If the refresh thread is waiting influshNormalNotificationsAndCompleteCycle()orflushAllNormalNotificationsForUnitTests(BooleanSupplier, long), wake it up.
-
Enum Constant Details
-
Method Details
-
values
Returns an array containing the constants of this enum type, in the order they are declared.- Returns:
- an array containing the constants of this enum type, in the order they are declared
-
valueOf
Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (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 type has no constant with the specified nameNullPointerException- if the argument is null
-
append
public com.fishlib.base.log.LogOutput append(@NotNull com.fishlib.base.log.LogOutput logOutput)- Specified by:
appendin interfacecom.fishlib.base.log.LogOutputAppendable
-
toString
- Overrides:
toStringin classEnum<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
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
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.Prefer {exclusiveLock()}.lock(). -
lockInterruptibly
Deprecated.Prefer {exclusiveLock()}.lockInterruptibly().- Throws:
InterruptedException
-
tryLock
Deprecated.Prefer {exclusiveLock()}.tryLock(). -
tryLock
@Deprecated public final boolean tryLock(long time, @NotNull TimeUnit unit) throws InterruptedExceptionDeprecated.Prefer {exclusiveLock()}.tryLock().- Throws:
InterruptedException
-
unlock
Deprecated.Prefer {exclusiveLock()}.unlock(). -
newCondition
Deprecated.Prefer {exclusiveLock()}.newCondition(). -
isLockedByCurrentThread
Deprecated.Test if this thread holds the lock (exclusively).- Returns:
- Whether the current thread holds the lock exclusively
-
doLocked
Deprecated.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 InterruptedExceptionDeprecated.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.Safely execute the supplied code while holding the lock.- Parameters:
r- the stuff to run
-
computeLocked
Deprecated.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 InterruptedExceptionDeprecated.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 extends ExceptionDeprecated.Safely execute the supplied code while holding the lock.- Parameters:
r- the stuff to run- Throws:
T- exception of type TT extends Exception
-
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
Execute the supplied code while table operations are unchecked.- Parameters:
supplier- the function to run- Returns:
- the result of supplier
-
doUnchecked
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
currentminimum 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 asrefreshing. Additionallystart()may not be called. -
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 watchdogtimeoutvalue.- Returns:
- The current timeout for the watchdog, 0 for disabled
-
setWatchDogTimeoutProcedure
Set the procedure to be called when the watchdogtimes out.- Parameters:
procedure- The procedure to call
-
requestSignal
-
start
public void start()Start the table refresh thread.- ImplNote:
- Must not be in
unit testmode.
-
addTable
Add a table to the list of tables to refresh and mark it asrefreshingif it was aDynamicNode.- Specified by:
addTablein interfaceLiveTableRegistrar- Parameters:
table- The table to be added to the refresh list- ImplNote:
- This will do nothing in
unit testmode other than mark the table as refreshing.
-
removeTable
Description copied from interface:LiveTableRegistrarRemove a table from this registrar.- Specified by:
removeTablein interfaceLiveTableRegistrar- Parameters:
liveTable- The table to remove
-
removeTables
Remove a collection of tables from the list of refreshing tables.- Parameters:
tablesToRemove- The tables to remove from the list of refreshing tables- ImplNote:
- This will not set the tables as
non-refreshing.
-
addNotification
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 aLiveTable.refresh()or subsequent notification delivery.- Specified by:
addNotificationin interfaceNotificationQueue- Parameters:
notification- The notification to enqueue- See Also:
NotificationQueue.Notification.isTerminal(),LogicalClock.State
-
maybeAddNotification
public boolean maybeAddNotification(@NotNull NotificationQueue.Notification notification, long deliveryStep)Description copied from interface:NotificationQueueAdd 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:
maybeAddNotificationin interfaceNotificationQueue- Parameters:
notification- The notification to adddeliveryStep- The step to deliver this notification on
-
satisfied
public boolean satisfied(long step)Description copied from interface:NotificationQueue.DependencyIs this ancestor satisfied? Note that this method must be safe to call on any thread.- Specified by:
satisfiedin interfaceNotificationQueue.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.- Parameters:
notifications- The notification to enqueue- See Also:
addNotification(Notification)
-
maybeRefreshTable
Acquire the exclusive lock if necessary and do a refresh ofliveTableon this thread if it is registered with this LTM.- Specified by:
maybeRefreshTablein interfaceLiveTableRegistrar- Parameters:
liveTable- TheLiveTablethat we would like to refreshonlyIfHaveLock- If true, check that the lock is held first and do nothing if it is not
-
requestRefresh
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:
requestRefreshin interfaceLiveTableRegistrar- Parameters:
liveTable- Thelive tableto refresh
-
resetForUnitTests
Clear all monitored tables and enqueued notifications to supportunit-tests. -
resetForUnitTests
@TestUseOnly public void resetForUnitTests(boolean randomizedNotifications, int seed, int maxRandomizedThreadCount, int notificationStartDelay, int notificationAdditionDelay) -
startCycleForUnitTests
Begin the nextupdate cyclewhile inunit-testmode. Note that this happens on a simulated LTM refresh thread, rather than this thread. -
startCycleForUnitTests
Begin the nextupdate cyclewhile inunit-testmode. 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 callrootRefreshCompleteForUnitTests()
-
rootRefreshCompleteForUnitTests
Mark the root tables satisfied within a unit test. -
completeCycleForUnitTests
Do the second half of the update cycle, including flushing notifications, and completing theLogicalClockupdate 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 extends ExceptionExecute the given runnable wrapped withstartCycleForUnitTests()andcompleteCycleForUnitTests(). Note that the runnable is run on the current thread.- Parameters:
runnable- the runnable to execute.- Throws:
T extends Exception
-
refreshLiveTableForUnitTests
Refresh aLiveTableon a simulated LTM refresh thread, rather than this thread.- Parameters:
liveTable- TheLiveTableto refresh
-
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
-
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 untildonereturnstrue. 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
If the refresh thread is waiting influshNormalNotificationsAndCompleteCycle()orflushAllNormalNotificationsForUnitTests(BooleanSupplier, long), wake it up. -
logDependencies
-