src/Pure/Build/build_schedule.scala
changeset 79877 9aef1d1535ff
parent 79871 630a82f87310
child 79878 841d0a1a9e48
--- a/src/Pure/Build/build_schedule.scala	Tue Mar 12 16:20:02 2024 +0000
+++ b/src/Pure/Build/build_schedule.scala	Tue Mar 12 13:52:29 2024 +0100
@@ -37,6 +37,7 @@
     def make(
       host_infos: Host_Infos,
       build_history: List[(Build_Log.Meta_Info, Build_Log.Build_Info)],
+      session_structure: Sessions.Structure,
     ): Timing_Data = {
       val hosts = host_infos.hosts
       val measurements =
@@ -62,10 +63,14 @@
               Result(job_name, hostname, threads, median_timing(timings))
           }
 
-      new Timing_Data(new Facet(entries), host_infos)
+      new Timing_Data(new Facet(entries), host_infos, session_structure)
     }
 
-    def load(host_infos: Host_Infos, log_database: SQL.Database): Timing_Data = {
+    def load(
+      host_infos: Host_Infos,
+      log_database: SQL.Database,
+      sessions_structure: Sessions.Structure
+    ): Timing_Data = {
       val build_history =
         for {
           log_name <- log_database.execute_query_statement(
@@ -75,7 +80,7 @@
           build_info = Build_Log.private_data.read_build_info(log_database, log_name)
         } yield (meta_info, build_info)
 
-      make(host_infos, build_history)
+      make(host_infos, build_history, sessions_structure)
     }
 
 
@@ -102,7 +107,11 @@
     }
   }
 
-  class Timing_Data private(facet: Timing_Data.Facet, val host_infos: Host_Infos) {
+  class Timing_Data private(
+    facet: Timing_Data.Facet,
+    val host_infos: Host_Infos,
+    val sessions_structure: Sessions.Structure
+  ) {
     private def inflection_point(last_mono: Int, next: Int): Int =
       last_mono + ((next - last_mono) / 2)
 
@@ -250,13 +259,23 @@
       def estimate: Time =
         facet.by_job.get(job_name) match {
           case None =>
-            // no data for job, take average of other jobs for given threads
-            val job_estimates = facet.by_job.keys.flatMap(estimate_threads(_, hostname, threads))
-            if (job_estimates.nonEmpty) Timing_Data.mean_time(job_estimates)
+            // no data for job, use timeout as esimation for single-threaded job on worst host
+            val default_time = sessions_structure(job_name).timeout
+            if (default_time > Time.zero) {
+              val default_host = host_infos.hosts.sorted(host_infos.host_speeds).head
+              default_time
+                .scale(global_threads_factor(1, threads))
+                .scale(hostname_factor(default_host.name, hostname))
+            }
             else {
-              // no other job to estimate from, use global curve to approximate any other job
-              val (threads1, facet1) = facet.by_threads.head
-              facet1.mean_time.scale(global_threads_factor(threads1, threads))
+              // no timeout, take average of other jobs for given threads
+              val job_estimates = facet.by_job.keys.flatMap(estimate_threads(_, hostname, threads))
+              if (job_estimates.nonEmpty) Timing_Data.mean_time(job_estimates)
+              else {
+                // no other job to estimate from, use global curve to approximate any other job
+                val (threads1, facet1) = facet.by_threads.head
+                facet1.mean_time.scale(global_threads_factor(threads1, threads))
+              }
             }
 
           case Some(facet) =>
@@ -940,7 +959,7 @@
         }
 
       val host_infos = Host_Infos.load(cluster_hosts, _host_database)
-      Timing_Data.load(host_infos, _log_database)
+      Timing_Data.load(host_infos, _log_database, build_context.sessions_structure)
     }
     private val scheduler = init_scheduler(timing_data)
 
@@ -1324,7 +1343,7 @@
       }
 
       val host_infos = Host_Infos.load(cluster_hosts, host_database)
-      val timing_data = Timing_Data.load(host_infos, log_database)
+      val timing_data = Timing_Data.load(host_infos, log_database, full_sessions)
 
       val sessions = Build_Process.Sessions.empty.init(build_context, database_server, progress)