src/Pure/Admin/isabelle_cronjob.scala
changeset 65783 d3d5cb2d6866
parent 65771 688a7dd22cbb
child 65785 6107504371fb
equal deleted inserted replaced
65782:4935bac8a850 65783:d3d5cb2d6866
    71       })
    71       })
    72 
    72 
    73 
    73 
    74   /* remote build_history */
    74   /* remote build_history */
    75 
    75 
       
    76   sealed case class Item(known: Boolean, isabelle_version: String, pull_date: Date)
       
    77   {
       
    78     def unknown: Boolean = !known
       
    79   }
       
    80 
    76   sealed case class Remote_Build(
    81   sealed case class Remote_Build(
    77     description: String,
    82     description: String,
    78     host: String,
    83     host: String,
    79     user: String = "",
    84     user: String = "",
    80     port: Int = 0,
    85     port: Int = 0,
    81     shared_home: Boolean = true,
    86     shared_home: Boolean = true,
    82     options: String = "",
    87     options: String = "",
    83     args: String = "",
    88     args: String = "",
    84     detect: SQL.Source = "")
    89     detect: SQL.Source = "")
    85   {
    90   {
       
    91     def sql: SQL.Source =
       
    92       Build_Log.Prop.build_engine + " = " + SQL.string(Build_History.engine) + " AND " +
       
    93       Build_Log.Prop.build_host + " = " + SQL.string(host) +
       
    94       (if (detect == "") "" else " AND " + SQL.enclose(detect))
       
    95 
    86     def profile: Build_Status.Profile =
    96     def profile: Build_Status.Profile =
       
    97       Build_Status.Profile(description, sql)
       
    98 
       
    99     def pick(options: Options, rev: String = ""): Option[String] =
    87     {
   100     {
    88       val sql =
   101       val store = Build_Log.store(options)
    89         Build_Log.Prop.build_engine + " = " + SQL.string(Build_History.engine) + " AND " +
   102       using(store.open_database())(db =>
    90         Build_Log.Prop.build_host + " = " + SQL.string(host) +
   103       {
    91         (if (detect == "") "" else " AND " + SQL.enclose(detect))
   104         val select =
    92       Build_Status.Profile(description, sql)
   105           Build_Log.Data.select_recent_isabelle_versions(
       
   106             days = options.int("build_log_history"), rev = rev, sql = "WHERE " + sql)
       
   107 
       
   108         val recent_items =
       
   109           db.using_statement(select)(stmt =>
       
   110             stmt.execute_query().iterator(res =>
       
   111             {
       
   112               val known = res.bool(Build_Log.Data.known)
       
   113               val isabelle_version = res.string(Build_Log.Prop.isabelle_version)
       
   114               val pull_date = res.date(Build_Log.Data.pull_date)
       
   115               Item(known, isabelle_version, pull_date)
       
   116             }).toList)
       
   117 
       
   118         def unknown_runs(items: List[Item]): List[List[Item]] =
       
   119         {
       
   120           val (run, rest) = Library.take_prefix[Item](_.unknown, items.dropWhile(_.known))
       
   121           if (run.nonEmpty) run :: unknown_runs(rest) else Nil
       
   122         }
       
   123 
       
   124         if (rev == "" || recent_items.exists(item => item.known && item.isabelle_version == rev)) {
       
   125           unknown_runs(recent_items).sortBy(_.length).reverse match {
       
   126             case longest_run :: _ => Some(longest_run(longest_run.length / 2).isabelle_version)
       
   127             case _ => None
       
   128           }
       
   129         }
       
   130         else Some(rev)
       
   131       })
    93     }
   132     }
    94   }
   133   }
    95 
   134 
    96   private val remote_builds: List[List[Remote_Build]] =
   135   private val remote_builds: List[List[Remote_Build]] =
    97   {
   136   {
   304     File.write(main_state_file, main_start_date + " " + log_service.hostname)
   343     File.write(main_state_file, main_start_date + " " + log_service.hostname)
   305 
   344 
   306     val rev = Mercurial.repository(isabelle_repos).id()
   345     val rev = Mercurial.repository(isabelle_repos).id()
   307 
   346 
   308     run(main_start_date,
   347     run(main_start_date,
   309       Logger_Task("isabelle_cronjob", _ =>
   348       Logger_Task("isabelle_cronjob", logger =>
   310         run_now(
   349         run_now(
   311           SEQ(List(build_release, build_history_base,
   350           SEQ(List(build_release, build_history_base,
   312             PAR(remote_builds.map(seq => SEQ(seq.map(remote_build_history(rev, _))))),
   351             PAR(remote_builds.map(seq =>
       
   352               SEQ(seq.flatMap(r => r.pick(logger.options, rev).map(remote_build_history(_, r)))))),
   313             Logger_Task("jenkins_logs", _ => Jenkins.download_logs(jenkins_jobs, main_dir)),
   353             Logger_Task("jenkins_logs", _ => Jenkins.download_logs(jenkins_jobs, main_dir)),
   314             Logger_Task("build_log_database",
   354             Logger_Task("build_log_database",
   315               logger => Isabelle_Devel.build_log_database(logger.options)),
   355               logger => Isabelle_Devel.build_log_database(logger.options)),
   316             Logger_Task("build_status",
   356             Logger_Task("build_status",
   317               logger => Isabelle_Devel.build_status(logger.options)))))))
   357               logger => Isabelle_Devel.build_status(logger.options)))))))