Skip to content

Instantly share code, notes, and snippets.

@fridoo
Last active February 29, 2020 12:38
Show Gist options
  • Save fridoo/a8f678904710a758c86ec80442124024 to your computer and use it in GitHub Desktop.
Save fridoo/a8f678904710a758c86ec80442124024 to your computer and use it in GitHub Desktop.
App.SCHEDULER = componentContext
// ----------
private fun startRandomSwitches(locationId: String, parameters: RandomSwitchParameters): FixedExecutionTask {
LOGGER.debug("startRandomSwitches: {}", App.GSON.toJson(parameters))
return with(
RandomSwitchGenerator(
locationId,
IlluminationEnvironment.CAV_FACTORY,
parameters.propertiesToSwitch,
mapOf(
Properties.on.get() to AppConfiguration.ON_PROBABILITY,
Properties.dimmingLevel.get() to AppConfiguration.DIM_PROBABILITY,
Properties.blindLevel.get() to AppConfiguration.BLIND_PROBABILITY,
ObservableUiProperty.TARGET_ILLUMINANCE.name to AppConfiguration.TARGET_ILLUMINANCE_PROBABILITY
),
parameters.minTargetIlluminance,
parameters.maxTargetIlluminance,
parameters.seed.value
)
) {
FixedExecutionTask.runNTimes(
{ nextRandom(true) },
parameters.numberOfSwitches,
parameters.periodInMillis.toLong(),
TimeUnit.MILLISECONDS
)
}
}
class FixedExecutionTask private constructor(
private val delegate: () -> Unit,
private val maxRunCount: Int,
private val period: Long
) : Runnable {
private val runCount = AtomicInteger()
@Volatile
private var self: ScheduledFuture<*>? = null
val status: FixedExecutionTaskStatus
get() = FixedExecutionTaskStatus(runCount.get(), maxRunCount, period)
override fun run() {
if (runCount.incrementAndGet() <= maxRunCount) {
LOGGER.info("RUN executing")
return delegate()
}
LOGGER.info("RUN N TIMES - reached end - ThreadId: {}", Thread.currentThread().id)
try {
Thread.sleep(period)
} catch (e: InterruptedException) {
LOGGER.warn("Thread interrupted after Utils.runNTimes ran {} times", runCount.get())
}
var interrupted = false
try {
while (self == null) {
try {
Thread.sleep(1)
} catch (e: InterruptedException) {
interrupted = true
}
}
self!!.cancel(false)
} finally {
if (interrupted) Thread.currentThread().interrupt()
}
}
// Cancellation is considered a success because the supplied task is cancelled after n iterations
fun await() = try { self?.get() } catch (e: CancellationException) { }
fun cancel(mayInterruptIfRunning: Boolean = true) = self?.cancel(mayInterruptIfRunning)
@FrontendModel
class FixedExecutionTaskStatus(val currentRunCount: Int = 0, val maxRunCount: Int = 0, val period: Long = 0)
companion object {
private val LOGGER = LoggerFactory.getLogger(FixedExecutionTask::class.java)
fun runNTimes(
task: () -> Unit,
maxRunCount: Int,
period: Long,
unit: TimeUnit,
executor: Scheduler = App.SCHEDULER
) = FixedExecutionTask(task, maxRunCount, period).apply {
self = executor.scheduleAtFixedRate(this, 0, period, unit)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment