diff options
| author | Dante Niewenhuis <d.niewenhuis@hotmail.com> | 2025-11-04 21:09:38 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-04 21:09:38 +0100 |
| commit | 71f63618fb83c8e19ae48d5dc4a6e3927031cc10 (patch) | |
| tree | 6bf4048b1e683bbcac53e162be787e80828e48e2 /opendc-compute/opendc-compute-simulator/src/main/kotlin | |
| parent | 59898b873eabc72719376854770c55e8d8efaa0f (diff) | |
Memory update (#379)
* Updated the memory usage of Tasks. Still in Progress.
* Merged Task and ServiceTask -> Currently not fully working!!!
* Fixed bugs that made the merger between Task and ServiceTask not work well.
* Updated jdk version for Dockerfile
* Removed ServiceFlavor.java and Task.kt
Diffstat (limited to 'opendc-compute/opendc-compute-simulator/src/main/kotlin')
16 files changed, 70 insertions, 65 deletions
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt index 856cfd3b..cb7d028c 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/host/SimHost.kt @@ -23,7 +23,6 @@ package org.opendc.compute.simulator.host import org.opendc.common.ResourceType -import org.opendc.compute.api.Flavor import org.opendc.compute.api.TaskState import org.opendc.compute.simulator.internal.Guest import org.opendc.compute.simulator.internal.GuestListener @@ -231,9 +230,9 @@ public class SimHost( } public fun canFit(task: ServiceTask): Boolean { - val sufficientMemory = model.memoryCapacity >= task.flavor.memorySize - val enoughCpus = model.coreCount >= task.flavor.cpuCoreCount - val canFit = simMachine!!.canFit(task.flavor.toMachineModel()) + val sufficientMemory = model.memoryCapacity >= task.memorySize + val enoughCpus = model.coreCount >= task.cpuCoreCount + val canFit = simMachine!!.canFit(task.toMachineModel()) return sufficientMemory && enoughCpus && canFit } @@ -404,10 +403,10 @@ public class SimHost( /** * Convert flavor to machine model. */ - private fun Flavor.toMachineModel(): MachineModel { + private fun ServiceTask.toMachineModel(): MachineModel { return MachineModel( simMachine!!.machineModel.cpuModel, - MemoryUnit("Generic", "Generic", 3200.0, memorySize), + MemoryUnit("Generic", "Generic", 3200.0, this.memorySize), simMachine!!.machineModel.gpuModels, simMachine!!.machineModel.cpuDistributionStrategy, simMachine!!.machineModel.gpuDistributionStrategy, diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/DifferentHostFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/DifferentHostFilter.kt index bc98a575..9d0006a4 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/DifferentHostFilter.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/DifferentHostFilter.kt @@ -34,7 +34,8 @@ public class DifferentHostFilter : HostFilter { task: ServiceTask, ): Boolean { @Suppress("UNCHECKED_CAST") - val affinityIDs = task.meta["scheduler_hint:different_host"] as? Set<Int> ?: return true - return host.host.getInstances().none { it.id in affinityIDs } + return true // TODO: re-enable different_host filter +// val affinityIDs = task.meta["scheduler_hint:different_host"] as? Set<Int> ?: return true +// return host.host.getInstances().none { it.id in affinityIDs } } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/RamFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/RamFilter.kt index fcc5e49c..a58cd408 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/RamFilter.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/RamFilter.kt @@ -37,9 +37,9 @@ public class RamFilter(private val allocationRatio: Double = 1.0) : HostFilter { host: HostView, task: ServiceTask, ): Boolean { - if (isSimple) return host.availableMemory >= task.flavor.memorySize + if (isSimple) return host.availableMemory >= task.memorySize - val requestedMemory = task.flavor.memorySize + val requestedMemory = task.memorySize val availableMemory = host.availableMemory val memoryCapacity = host.host.getModel().memoryCapacity diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/SameHostFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/SameHostFilter.kt index 73fd0d3c..8d5048d3 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/SameHostFilter.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/SameHostFilter.kt @@ -34,7 +34,8 @@ public class SameHostFilter : HostFilter { task: ServiceTask, ): Boolean { @Suppress("UNCHECKED_CAST") - val affinityIDs = task.meta["scheduler_hint:same_host"] as? Set<Int> ?: return true - return host.host.getInstances().any { it.id in affinityIDs } +// val affinityIDs = task.meta["scheduler_hint:same_host"] as? Set<Int> ?: return true +// return host.host.getInstances().any { it.id in affinityIDs } + return true } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuCapacityFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuCapacityFilter.kt index 7fa7a051..72d6be97 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuCapacityFilter.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuCapacityFilter.kt @@ -34,13 +34,10 @@ public class VCpuCapacityFilter : HostFilter { host: HostView, task: ServiceTask, ): Boolean { - val requiredCapacity = task.flavor.meta["cpu-capacity"] as? Double + val requiredCapacity = task.cpuCapacity val availableCapacity = host.host.getModel().cpuCapacity - return ( - requiredCapacity == null || - (availableCapacity / host.host.getModel().coreCount) - >= (requiredCapacity / task.flavor.cpuCoreCount) - ) + return (availableCapacity / host.host.getModel().coreCount) >= + (requiredCapacity / task.cpuCoreCount) } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuFilter.kt index a017c623..2b66fd17 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuFilter.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VCpuFilter.kt @@ -37,9 +37,9 @@ public class VCpuFilter(private val allocationRatio: Double = 1.0) : HostFilter host: HostView, task: ServiceTask, ): Boolean { - if (isSimple) return host.availableCpuCores >= task.flavor.cpuCoreCount + if (isSimple) return host.availableCpuCores >= task.cpuCoreCount - val requested = task.flavor.cpuCoreCount + val requested = task.cpuCoreCount val totalCores = host.host.getModel().coreCount // Do not allow an instance to overcommit against itself, only against other instances diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VGpuCapacityFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VGpuCapacityFilter.kt index 5f517257..bcb4a066 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VGpuCapacityFilter.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VGpuCapacityFilter.kt @@ -35,14 +35,11 @@ public class VGpuCapacityFilter : HostFilter { host: HostView, task: ServiceTask, ): Boolean { - val requiredCapacity = task.flavor.meta["gpu-capacity"] as? Double + val requiredCapacity = task.gpuCapacity val availableCapacity = (host.host.getModel().gpuHostModels().maxOfOrNull { it.gpuCoreCapacity() } ?: 0).toDouble() val availableCores = (host.host.getModel().gpuHostModels().maxOfOrNull { it -> it.gpuCoreCount } ?: -1).toDouble() val availableRatio = availableCapacity / availableCores - return ( - requiredCapacity == null || - (availableRatio >= (requiredCapacity / task.flavor.gpuCoreCount)) - ) + return availableRatio >= (requiredCapacity / task.gpuCoreCount) } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VGpuFilter.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VGpuFilter.kt index f47013b1..26855944 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VGpuFilter.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/filters/VGpuFilter.kt @@ -35,7 +35,7 @@ public class VGpuFilter(private val allocationRatio: Double) : HostFilter { host: HostView, task: ServiceTask, ): Boolean { - val requested = task.flavor.gpuCoreCount + val requested = task.gpuCoreCount val totalCores = host.host.getModel().gpuHostModels()?.sumOf { it.gpuCoreCount() } ?: 0 val limit = totalCores * allocationRatio diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/timeshift/MemorizingTimeshift.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/timeshift/MemorizingTimeshift.kt index e0488e30..f84d1a4b 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/timeshift/MemorizingTimeshift.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/timeshift/MemorizingTimeshift.kt @@ -30,7 +30,6 @@ import org.opendc.compute.simulator.scheduler.filters.HostFilter import org.opendc.compute.simulator.service.HostView import org.opendc.compute.simulator.service.ServiceTask import org.opendc.simulator.compute.power.CarbonModel -import java.time.Instant import java.time.InstantSource import java.util.LinkedList @@ -126,18 +125,25 @@ public class MemorizingTimeshift( Only delay tasks if they are deferrable and it doesn't violate the deadline. Separate delay thresholds for short and long tasks. */ - if (task.nature.deferrable) { - val durInHours = task.duration.toHours() + if (task.deferrable) { + val durInHours = task.duration / (1000.0 * 60.0 * 60.0) if ((durInHours < 2 && !shortLowCarbon) || (durInHours >= 2 && !longLowCarbon) ) { - val currentTime = clock.instant() - val estimatedCompletion = currentTime.plus(task.duration) - val deadline = Instant.ofEpochMilli(task.deadline) - if (estimatedCompletion.isBefore(deadline)) { + val currentTime = clock.millis() + val estimatedCompletion = currentTime + task.duration + val deadline = task.deadline + if (estimatedCompletion <= deadline) { // No need to schedule this task in a high carbon intensity period continue } +// val currentTime = clock.instant() +// val estimatedCompletion = currentTime.plus(task.duration) +// val deadline = Instant.ofEpochMilli(task.deadline) +// if (estimatedCompletion.isBefore(deadline)) { +// // No need to schedule this task in a high carbon intensity period +// continue +// } } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/timeshift/TimeshiftScheduler.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/timeshift/TimeshiftScheduler.kt index 58b8904b..535336e8 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/timeshift/TimeshiftScheduler.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/timeshift/TimeshiftScheduler.kt @@ -31,7 +31,6 @@ import org.opendc.compute.simulator.scheduler.weights.HostWeigher import org.opendc.compute.simulator.service.HostView import org.opendc.compute.simulator.service.ServiceTask import org.opendc.simulator.compute.power.CarbonModel -import java.time.Instant import java.time.InstantSource import java.util.LinkedList import java.util.SplittableRandom @@ -96,15 +95,15 @@ public class TimeshiftScheduler( Only delay tasks if they are deferrable and it doesn't violate the deadline. Separate delay thresholds for short and long tasks. */ - if (task.nature.deferrable) { - val durInHours = task.duration.toHours() + if (task.deferrable) { + val durInHours = task.duration / (1000.0 * 60.0 * 60.0) if ((durInHours < 2 && !shortLowCarbon) || (durInHours >= 2 && !longLowCarbon) ) { - val currentTime = clock.instant() - val estimatedCompletion = currentTime.plus(task.duration) - val deadline = Instant.ofEpochMilli(task.deadline) - if (estimatedCompletion.isBefore(deadline)) { + val currentTime = clock.millis() + val estimatedCompletion = currentTime + task.duration + val deadline = task.deadline + if (estimatedCompletion < deadline) { // No need to schedule this task in a high carbon intensity period continue } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VCpuCapacityWeigher.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VCpuCapacityWeigher.kt index d9b094fb..65cc66a7 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VCpuCapacityWeigher.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VCpuCapacityWeigher.kt @@ -34,8 +34,8 @@ public class VCpuCapacityWeigher(override val multiplier: Double = 1.0) : HostWe task: ServiceTask, ): Double { val model = host.host.getModel() - val requiredCapacity = task.flavor.meta["cpu-capacity"] as? Double ?: 0.0 - return model.cpuCapacity - requiredCapacity / task.flavor.cpuCoreCount + val requiredCapacity = task.cpuCapacity + return model.cpuCapacity - requiredCapacity / task.cpuCoreCount } override fun toString(): String = "VCpuWeigher" diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VGpuCapacityWeigher.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VGpuCapacityWeigher.kt index 35f2c7b9..78c49271 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VGpuCapacityWeigher.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/weights/VGpuCapacityWeigher.kt @@ -34,9 +34,9 @@ public class VGpuCapacityWeigher(override val multiplier: Double = 1.0) : HostWe task: ServiceTask, ): Double { val model = host.host.getModel() - val requiredCapacity = task.flavor.meta["gpu-capacity"] as? Double ?: 0.0 + val requiredCapacity = task.gpuCapacity val availableCapacity = model.gpuHostModels.maxOfOrNull { it.gpuCoreCapacity } ?: 0.0 - return availableCapacity - requiredCapacity / task.flavor.gpuCoreCount + return availableCapacity - requiredCapacity / task.gpuCoreCount } override fun toString(): String = "VGpuWeigher" diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt index 0397b9a1..b88c75e6 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/parquet/DfltTaskExportColumns.kt @@ -71,7 +71,12 @@ public object DfltTaskExportColumns { Types.required(BINARY) .`as`(LogicalTypeAnnotation.stringType()) .named("task_name"), - ) { Binary.fromString(it.taskInfo.name) } + ) { + if (it.taskInfo.name == null) { + return@ExportColumn Binary.fromString("") + } + return@ExportColumn Binary.fromString(it.taskInfo.name) + } public val HOST_NAME: ExportColumn<TaskTableReader> = ExportColumn( @@ -194,17 +199,17 @@ public object DfltTaskExportColumns { public val SCHEDULE_TIME: ExportColumn<TaskTableReader> = ExportColumn( field = Types.optional(INT64).named("schedule_time"), - ) { it.scheduleTime?.toEpochMilli() } + ) { it.scheduleTime } public val SUBMISSION_TIME: ExportColumn<TaskTableReader> = ExportColumn( field = Types.optional(INT64).named("submission_time"), - ) { it.submissionTime?.toEpochMilli() } + ) { it.submissionTime } public val FINISH_TIME: ExportColumn<TaskTableReader> = ExportColumn( field = Types.optional(INT64).named("finish_time"), - ) { it.finishTime?.toEpochMilli() } + ) { it.finishTime } public val TASK_STATE: ExportColumn<TaskTableReader> = ExportColumn( diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskInfo.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskInfo.kt index 2727847f..c23f3fb5 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskInfo.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskInfo.kt @@ -27,7 +27,7 @@ package org.opendc.compute.simulator.telemetry.table.task */ public data class TaskInfo( val id: Int, - val name: String, + val name: String?, val type: String, val arch: String, val cpuCount: Int, diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt index e3860606..1f18ee50 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReader.kt @@ -83,17 +83,17 @@ public interface TaskTableReader : Exportable { /** * The [Instant] at which the task was scheduled relative to the start of the workload. */ - public val scheduleTime: Instant? + public val scheduleTime: Long? /** * The [Instant] at which the task was submitted relative to the start of the workload. */ - public val submissionTime: Instant? + public val submissionTime: Long? /** * The [Instant] at which the task finished relative to the start of the workload. */ - public val finishTime: Instant? + public val finishTime: Long? /** * The capacity of the CPUs of Host on which the task is running (in MHz). diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt index 3183cf11..d4d5c7a6 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/table/task/TaskTableReaderImpl.kt @@ -93,9 +93,9 @@ public class TaskTableReaderImpl( task.name, "vm", "x86", - task.flavor.cpuCoreCount, - task.flavor.memorySize, - task.flavor.gpuCoreCount, + task.cpuCoreCount, + task.memorySize, + task.gpuCoreCount, ) /** @@ -134,17 +134,17 @@ public class TaskTableReaderImpl( get() = _numPauses private var _numPauses = 0 - override val submissionTime: Instant? + override val submissionTime: Long? get() = _submissionTime - private var _submissionTime: Instant? = null + private var _submissionTime: Long? = null - override val scheduleTime: Instant? + override val scheduleTime: Long? get() = _scheduleTime - private var _scheduleTime: Instant? = null + private var _scheduleTime: Long? = null - override val finishTime: Instant? + override val finishTime: Long? get() = _finishTime - private var _finishTime: Instant? = null + private var _finishTime: Long? = null override val cpuLimit: Double get() = _cpuLimit @@ -190,22 +190,22 @@ public class TaskTableReaderImpl( get() = _gpuDemand private var _gpuDemand: Double? = 0.0 - override val gpuActiveTime: Long? + override val gpuActiveTime: Long get() = (_gpuActiveTime ?: 0L) - (previousGpuActiveTime ?: 0L) private var _gpuActiveTime: Long? = null private var previousGpuActiveTime: Long? = null - override val gpuIdleTime: Long? + override val gpuIdleTime: Long get() = (_gpuIdleTime ?: 0L) - (previousGpuIdleTime ?: 0L) private var _gpuIdleTime: Long? = null private var previousGpuIdleTime: Long? = null - override val gpuStealTime: Long? + override val gpuStealTime: Long get() = (_gpuStealTime ?: 0L) - (previousGpuStealTime ?: 0L) private var _gpuStealTime: Long? = null private var previousGpuStealTime: Long? = null - override val gpuLostTime: Long? + override val gpuLostTime: Long get() = (_gpuLostTime ?: 0L) - (previousGpuLostTime ?: 0L) private var _gpuLostTime: Long? = null private var previousGpuLostTime: Long? = null |
