src/Pure/System/progress.scala
author wenzelm
Tue, 04 Nov 2025 22:36:39 +0100
changeset 83510 0675f4daf3c0
parent 83509 d17e990ebd40
child 83512 8767da4c15a8
permissions -rw-r--r--
clarified messages;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
61276
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/System/progress.scala
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
     3
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
     4
Progress context for system processes.
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
     5
*/
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
     6
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
     7
package isabelle
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
     8
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
     9
73897
0ddb5de0506e clarified signature: prefer Java interfaces;
wenzelm
parents: 73367
diff changeset
    10
import java.util.{Map => JMap}
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
    11
import scala.collection.mutable
64201
wenzelm
parents: 64117
diff changeset
    12
wenzelm
parents: 64117
diff changeset
    13
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73897
diff changeset
    14
object Progress {
78503
6dc1ea827870 clarified signature: more explicit types;
wenzelm
parents: 78432
diff changeset
    15
  /* output */
6dc1ea827870 clarified signature: more explicit types;
wenzelm
parents: 78432
diff changeset
    16
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
    17
  sealed abstract class Msg {
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
    18
    def verbose: Boolean
83285
ec2bd302560c support explicit message status, e.g. for specific output;
wenzelm
parents: 83284
diff changeset
    19
    def status: Boolean
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
    20
    def message: Message
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
    21
  }
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
    22
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
    23
  type Output = List[Msg]
83304
7d9d730a8fd0 more robust treatment of parallel sessions;
wenzelm
parents: 83302
diff changeset
    24
  type Session_Output = List[(String, Msg)]
78155
54d6b2f75806 support for Database_Progress;
wenzelm
parents: 77524
diff changeset
    25
83284
a1caad269354 clarified signature: more direct function;
wenzelm
parents: 83283
diff changeset
    26
  def output_theory(msg: Msg): Msg =
a1caad269354 clarified signature: more direct function;
wenzelm
parents: 83283
diff changeset
    27
    msg match {
a1caad269354 clarified signature: more direct function;
wenzelm
parents: 83283
diff changeset
    28
      case thy: Theory if thy.verbose => thy.copy(verbose = false)
a1caad269354 clarified signature: more direct function;
wenzelm
parents: 83283
diff changeset
    29
      case _ => msg
a1caad269354 clarified signature: more direct function;
wenzelm
parents: 83283
diff changeset
    30
    }
a1caad269354 clarified signature: more direct function;
wenzelm
parents: 83283
diff changeset
    31
78611
7b80cc4701c2 clarified signature: prefer enum types;
wenzelm
parents: 78586
diff changeset
    32
  enum Kind { case writeln, warning, error_message }
78503
6dc1ea827870 clarified signature: more explicit types;
wenzelm
parents: 78432
diff changeset
    33
  sealed case class Message(
78611
7b80cc4701c2 clarified signature: prefer enum types;
wenzelm
parents: 78586
diff changeset
    34
    kind: Kind,
78503
6dc1ea827870 clarified signature: more explicit types;
wenzelm
parents: 78432
diff changeset
    35
    text: String,
83285
ec2bd302560c support explicit message status, e.g. for specific output;
wenzelm
parents: 83284
diff changeset
    36
    override val verbose: Boolean = false,
ec2bd302560c support explicit message status, e.g. for specific output;
wenzelm
parents: 83284
diff changeset
    37
    override val status: Boolean = false
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
    38
  ) extends Msg {
78503
6dc1ea827870 clarified signature: more explicit types;
wenzelm
parents: 78432
diff changeset
    39
    override def message: Message = this
6dc1ea827870 clarified signature: more explicit types;
wenzelm
parents: 78432
diff changeset
    40
83270
948825e90a18 minor performance tuning;
wenzelm
parents: 83269
diff changeset
    41
    lazy val output_text: String =
77502
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
    42
      kind match {
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
    43
        case Kind.writeln => Output.writeln_text(text)
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
    44
        case Kind.warning => Output.warning_text(text)
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
    45
        case Kind.error_message => Output.error_message_text(text)
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
    46
      }
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
    47
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
    48
    override def toString: String = output_text
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
    49
  }
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
    50
78503
6dc1ea827870 clarified signature: more explicit types;
wenzelm
parents: 78432
diff changeset
    51
  sealed case class Theory(
6dc1ea827870 clarified signature: more explicit types;
wenzelm
parents: 78432
diff changeset
    52
    theory: String,
6dc1ea827870 clarified signature: more explicit types;
wenzelm
parents: 78432
diff changeset
    53
    session: String = "",
83223
a225609e3344 support for detailed build progress;
wenzelm
parents: 83214
diff changeset
    54
    percentage: Option[Int] = None,
83289
2cd87a6da20b clarified command_timing: expose elapsed time only, other fields were never used;
wenzelm
parents: 83286
diff changeset
    55
    cumulated_time: Time = Time.zero,
83285
ec2bd302560c support explicit message status, e.g. for specific output;
wenzelm
parents: 83284
diff changeset
    56
    override val verbose: Boolean = true,
ec2bd302560c support explicit message status, e.g. for specific output;
wenzelm
parents: 83284
diff changeset
    57
    override val status: Boolean = false
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
    58
  ) extends Msg {
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
    59
    override def message: Message =
83289
2cd87a6da20b clarified command_timing: expose elapsed time only, other fields were never used;
wenzelm
parents: 83286
diff changeset
    60
      Message(Kind.writeln, print_session + print_theory + print_percentage + print_cumulated_time,
83285
ec2bd302560c support explicit message status, e.g. for specific output;
wenzelm
parents: 83284
diff changeset
    61
        verbose = verbose, status = status)
68987
e86d6e869b96 tuned signature;
wenzelm
parents: 68957
diff changeset
    62
77504
wenzelm
parents: 77503
diff changeset
    63
    def print_session: String = if_proper(session, session + ": ")
68987
e86d6e869b96 tuned signature;
wenzelm
parents: 68957
diff changeset
    64
    def print_theory: String = "theory " + theory
e86d6e869b96 tuned signature;
wenzelm
parents: 68957
diff changeset
    65
    def print_percentage: String =
e86d6e869b96 tuned signature;
wenzelm
parents: 68957
diff changeset
    66
      percentage match { case None => "" case Some(p) => " " + p + "%" }
83289
2cd87a6da20b clarified command_timing: expose elapsed time only, other fields were never used;
wenzelm
parents: 83286
diff changeset
    67
    def print_cumulated_time: String =
2cd87a6da20b clarified command_timing: expose elapsed time only, other fields were never used;
wenzelm
parents: 83286
diff changeset
    68
      if (cumulated_time.is_relevant) " (" + cumulated_time.message + " cumulated time)" else ""
68957
eef4e983fd9d clarified theory progress;
wenzelm
parents: 68951
diff changeset
    69
  }
83214
911fbc338de7 clarified signature: more explicit type Progress.Nodes_Status;
wenzelm
parents: 83205
diff changeset
    70
83315
03dfb684a50d more robust nodes_status_exit: make double-sure that progress.nodes_status is finally empty, even after a crash of the prover process (where command_timings might be missing);
wenzelm
parents: 83309
diff changeset
    71
  object Nodes_Status {
03dfb684a50d more robust nodes_status_exit: make double-sure that progress.nodes_status is finally empty, even after a crash of the prover process (where command_timings might be missing);
wenzelm
parents: 83309
diff changeset
    72
    def empty(session: String): Nodes_Status =
83507
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
    73
      Nodes_Status(Date.now(), Nil, Document_Status.Nodes_Status.empty, session = session)
83315
03dfb684a50d more robust nodes_status_exit: make double-sure that progress.nodes_status is finally empty, even after a crash of the prover process (where command_timings might be missing);
wenzelm
parents: 83309
diff changeset
    74
  }
03dfb684a50d more robust nodes_status_exit: make double-sure that progress.nodes_status is finally empty, even after a crash of the prover process (where command_timings might be missing);
wenzelm
parents: 83309
diff changeset
    75
83214
911fbc338de7 clarified signature: more explicit type Progress.Nodes_Status;
wenzelm
parents: 83205
diff changeset
    76
  sealed case class Nodes_Status(
83507
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
    77
    now: Date,
83214
911fbc338de7 clarified signature: more explicit type Progress.Nodes_Status;
wenzelm
parents: 83205
diff changeset
    78
    domain: List[Document.Node.Name],
83223
a225609e3344 support for detailed build progress;
wenzelm
parents: 83214
diff changeset
    79
    document_status: Document_Status.Nodes_Status,
83227
2ecfd436903b more informative Progress.Nodes_Status;
wenzelm
parents: 83224
diff changeset
    80
    session: String = "",
2ecfd436903b more informative Progress.Nodes_Status;
wenzelm
parents: 83224
diff changeset
    81
    old: Option[Document_Status.Nodes_Status] = None
83214
911fbc338de7 clarified signature: more explicit type Progress.Nodes_Status;
wenzelm
parents: 83205
diff changeset
    82
  ) {
83223
a225609e3344 support for detailed build progress;
wenzelm
parents: 83214
diff changeset
    83
    def apply(name: Document.Node.Name): Document_Status.Node_Status =
a225609e3344 support for detailed build progress;
wenzelm
parents: 83214
diff changeset
    84
      document_status(name)
a225609e3344 support for detailed build progress;
wenzelm
parents: 83214
diff changeset
    85
83298
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
    86
    def theory(
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
    87
      name: Document.Node.Name,
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
    88
      node_status: Document_Status.Node_Status,
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
    89
      status: Boolean = false): Theory =
83229
ad2b6030cb9c build_progress with percentage;
wenzelm
parents: 83227
diff changeset
    90
      Theory(theory = name.theory, session = session,
ad2b6030cb9c build_progress with percentage;
wenzelm
parents: 83227
diff changeset
    91
        percentage = Some(node_status.percentage),
83298
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
    92
        cumulated_time = node_status.cumulated_time,
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
    93
        status = status)
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
    94
83298
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
    95
    def old_percentage(name: Document.Node.Name): Int =
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
    96
      if (old.isEmpty) 0 else old.get(name).percentage
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
    97
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
    98
    def completed_theories: List[Theory] =
83298
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
    99
      domain.flatMap({ name =>
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   100
        val st = apply(name)
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   101
        val p = st.percentage
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   102
        if (p == 100 && p != old_percentage(name)) Some(theory(name, st)) else None
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   103
      })
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   104
83298
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   105
    def status_theories: List[Theory] =
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   106
      domain.flatMap({ name =>
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   107
        val st = apply(name)
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   108
        val p = st.percentage
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   109
        if (st.progress || (p < 100 && p != old_percentage(name))) {
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   110
          Some(theory(name, st, status = true))
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   111
        }
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   112
        else None
d2ffec6f4b89 clarified status_theories: show only running or updated theories;
wenzelm
parents: 83290
diff changeset
   113
      })
83507
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   114
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   115
    def status_commands(threshold: Time): List[Progress.Message] =
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   116
      List.from(
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   117
        for {
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   118
          name <- domain.iterator
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   119
          st = apply(name)
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   120
          command_timings <- st.command_timings.valuesIterator
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   121
          run <- command_timings.long_running(now, threshold).iterator
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   122
        } yield {
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   123
          val text =
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   124
            if_proper(session, session + ": ") +
83509
d17e990ebd40 tuned message;
wenzelm
parents: 83507
diff changeset
   125
              "command " + quote(run.name) + " running for " + run.time(now).message +
d17e990ebd40 tuned message;
wenzelm
parents: 83507
diff changeset
   126
              " (line " + run.line + " of theory " + quote(name.theory) + ")"
83510
0675f4daf3c0 clarified messages;
wenzelm
parents: 83509
diff changeset
   127
          Progress.Message(Progress.Kind.writeln, text, verbose = true)
83507
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   128
        })
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   129
  }
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   130
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   131
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   132
  /* status lines (e.g. at bottom of output) */
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   133
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   134
  trait Status extends Progress {
83507
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   135
    def status_threshold: Time = Time.zero
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   136
    def status_detailed: Boolean = false
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   137
83286
f772c9234f7f proper status_output for output via Progress.Status mixin;
wenzelm
parents: 83285
diff changeset
   138
    def status_output(msgs: Progress.Output): Unit
f772c9234f7f proper status_output for output via Progress.Status mixin;
wenzelm
parents: 83285
diff changeset
   139
83271
93db1865ee0e clarified Progress.Status: more general types;
wenzelm
parents: 83270
diff changeset
   140
    def status_hide(status: Progress.Output): Unit = ()
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   141
83304
7d9d730a8fd0 more robust treatment of parallel sessions;
wenzelm
parents: 83302
diff changeset
   142
    protected var _status: Progress.Session_Output = Nil
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   143
83304
7d9d730a8fd0 more robust treatment of parallel sessions;
wenzelm
parents: 83302
diff changeset
   144
    def status_clear(): Progress.Session_Output = synchronized {
83271
93db1865ee0e clarified Progress.Status: more general types;
wenzelm
parents: 83270
diff changeset
   145
      val status = _status
93db1865ee0e clarified Progress.Status: more general types;
wenzelm
parents: 83270
diff changeset
   146
      _status = Nil
83304
7d9d730a8fd0 more robust treatment of parallel sessions;
wenzelm
parents: 83302
diff changeset
   147
      status_hide(status.map(_._2))
83271
93db1865ee0e clarified Progress.Status: more general types;
wenzelm
parents: 83270
diff changeset
   148
      status
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   149
    }
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   150
83304
7d9d730a8fd0 more robust treatment of parallel sessions;
wenzelm
parents: 83302
diff changeset
   151
    private def output_status(status: Progress.Session_Output): Unit = synchronized {
83271
93db1865ee0e clarified Progress.Status: more general types;
wenzelm
parents: 83270
diff changeset
   152
      _status = Nil
83304
7d9d730a8fd0 more robust treatment of parallel sessions;
wenzelm
parents: 83302
diff changeset
   153
      status_output(status.map(_._2))
83271
93db1865ee0e clarified Progress.Status: more general types;
wenzelm
parents: 83270
diff changeset
   154
      _status = status
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   155
    }
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   156
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   157
    override def output(msgs: Progress.Output): Unit = synchronized {
83302
71ad306ee61f proper support for output_theory, notably for isabelle.jedit.Session_Build.progress;
wenzelm
parents: 83298
diff changeset
   158
      if (msgs.nonEmpty) {
83271
93db1865ee0e clarified Progress.Status: more general types;
wenzelm
parents: 83270
diff changeset
   159
        val status = status_clear()
83286
f772c9234f7f proper status_output for output via Progress.Status mixin;
wenzelm
parents: 83285
diff changeset
   160
        status_output(msgs)
f772c9234f7f proper status_output for output via Progress.Status mixin;
wenzelm
parents: 83285
diff changeset
   161
        output_status(status)
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   162
      }
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   163
    }
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   164
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   165
    override def nodes_status(nodes_status: Progress.Nodes_Status): Unit = synchronized {
83304
7d9d730a8fd0 more robust treatment of parallel sessions;
wenzelm
parents: 83302
diff changeset
   166
      val old_status = status_clear()
83309
1a0857d96637 minor performance tuning;
wenzelm
parents: 83306
diff changeset
   167
      val new_status = {
1a0857d96637 minor performance tuning;
wenzelm
parents: 83306
diff changeset
   168
        val buf = new mutable.ListBuffer[(String, Progress.Msg)]
1a0857d96637 minor performance tuning;
wenzelm
parents: 83306
diff changeset
   169
        val session = nodes_status.session
1a0857d96637 minor performance tuning;
wenzelm
parents: 83306
diff changeset
   170
        for (old <- old_status if old._1 < session) buf += old
83507
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   171
        if (status_detailed) {
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   172
          for (thy <- nodes_status.status_theories) buf += (session -> thy)
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   173
        }
83309
1a0857d96637 minor performance tuning;
wenzelm
parents: 83306
diff changeset
   174
        for (old <- old_status if old._1 > session) buf += old
1a0857d96637 minor performance tuning;
wenzelm
parents: 83306
diff changeset
   175
        buf.toList
1a0857d96637 minor performance tuning;
wenzelm
parents: 83306
diff changeset
   176
      }
83304
7d9d730a8fd0 more robust treatment of parallel sessions;
wenzelm
parents: 83302
diff changeset
   177
83510
0675f4daf3c0 clarified messages;
wenzelm
parents: 83509
diff changeset
   178
      output(nodes_status.completed_theories ::: nodes_status.status_commands(status_threshold))
83304
7d9d730a8fd0 more robust treatment of parallel sessions;
wenzelm
parents: 83302
diff changeset
   179
      output_status(new_status)
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   180
    }
83214
911fbc338de7 clarified signature: more explicit type Progress.Nodes_Status;
wenzelm
parents: 83205
diff changeset
   181
  }
68410
4e27f5c361d2 clarified signature: more uniform theory_message (see also d7920eb7de54);
wenzelm
parents: 68330
diff changeset
   182
}
4e27f5c361d2 clarified signature: more uniform theory_message (see also d7920eb7de54);
wenzelm
parents: 68330
diff changeset
   183
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73897
diff changeset
   184
class Progress {
78876
4222955f3b69 clarified signature: explicit Progress date;
wenzelm
parents: 78874
diff changeset
   185
  def now(): Date = Date.now()
4222955f3b69 clarified signature: explicit Progress date;
wenzelm
parents: 78874
diff changeset
   186
  val start: Date = now()
4222955f3b69 clarified signature: explicit Progress date;
wenzelm
parents: 78874
diff changeset
   187
77509
3bc49507bae5 clarified treatment of "verbose" messages, e.g. Progress.theory();
wenzelm
parents: 77507
diff changeset
   188
  def verbose: Boolean = false
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   189
  final def do_output(msg: Progress.Msg): Boolean = !msg.verbose || verbose
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   190
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   191
  def output(msgs: Progress.Output): Unit = {}
77509
3bc49507bae5 clarified treatment of "verbose" messages, e.g. Progress.theory();
wenzelm
parents: 77507
diff changeset
   192
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   193
  final def output_text(msgs: Progress.Output, terminate: Boolean = false): String = {
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   194
    val lines = msgs.flatMap(msg => if (do_output(msg)) Some(msg.message.output_text) else None)
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   195
    if (terminate) Library.terminate_lines(lines) else cat_lines(lines)
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   196
  }
77502
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
   197
77509
3bc49507bae5 clarified treatment of "verbose" messages, e.g. Progress.theory();
wenzelm
parents: 77507
diff changeset
   198
  final def echo(msg: String, verbose: Boolean = false): Unit =
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   199
    output(List(Progress.Message(Progress.Kind.writeln, msg, verbose = verbose)))
77509
3bc49507bae5 clarified treatment of "verbose" messages, e.g. Progress.theory();
wenzelm
parents: 77507
diff changeset
   200
  final def echo_warning(msg: String, verbose: Boolean = false): Unit =
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   201
    output(List(Progress.Message(Progress.Kind.warning, msg, verbose = verbose)))
77509
3bc49507bae5 clarified treatment of "verbose" messages, e.g. Progress.theory();
wenzelm
parents: 77507
diff changeset
   202
  final def echo_error_message(msg: String, verbose: Boolean = false): Unit =
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   203
    output(List(Progress.Message(Progress.Kind.error_message, msg, verbose = verbose)))
77502
2e2b2bd6b2d2 clarified signature: require just one "override def echo(message: Progress.Message): Unit";
wenzelm
parents: 77499
diff changeset
   204
77506
a8175b950173 more robust signature: avoid totally adhoc overriding (see also Build_Process.progress vs. build_progress);
wenzelm
parents: 77504
diff changeset
   205
  final def echo_if(cond: Boolean, msg: String): Unit = if (cond) echo(msg)
77499
8fc94efa954a clarified signature: more uniform Progress.verbose, avoid adhoc "override def theory()";
wenzelm
parents: 77498
diff changeset
   206
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   207
  final def theory(theory: Progress.Theory): Unit = output(List(theory))
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   208
83214
911fbc338de7 clarified signature: more explicit type Progress.Nodes_Status;
wenzelm
parents: 83205
diff changeset
   209
  def nodes_status(nodes_status: Progress.Nodes_Status): Unit = {}
64909
8007f10195af tuned signature;
wenzelm
parents: 64201
diff changeset
   210
78432
ee5d9ecc6a0a tuned signature;
wenzelm
parents: 78396
diff changeset
   211
  final def capture[A](e: => A, msg: String, err: Throwable => String): Exn.Result[A] = {
ee5d9ecc6a0a tuned signature;
wenzelm
parents: 78396
diff changeset
   212
    echo(msg)
ee5d9ecc6a0a tuned signature;
wenzelm
parents: 78396
diff changeset
   213
    try { Exn.Res(e) }
ee5d9ecc6a0a tuned signature;
wenzelm
parents: 78396
diff changeset
   214
    catch { case exn: Throwable => echo_error_message(err(exn)); Exn.Exn[A](exn) }
ee5d9ecc6a0a tuned signature;
wenzelm
parents: 78396
diff changeset
   215
  }
ee5d9ecc6a0a tuned signature;
wenzelm
parents: 78396
diff changeset
   216
77506
a8175b950173 more robust signature: avoid totally adhoc overriding (see also Build_Process.progress vs. build_progress);
wenzelm
parents: 77504
diff changeset
   217
  final def timeit[A](
a8175b950173 more robust signature: avoid totally adhoc overriding (see also Build_Process.progress vs. build_progress);
wenzelm
parents: 77504
diff changeset
   218
    body: => A,
a8175b950173 more robust signature: avoid totally adhoc overriding (see also Build_Process.progress vs. build_progress);
wenzelm
parents: 77504
diff changeset
   219
    message: Exn.Result[A] => String = null,
a8175b950173 more robust signature: avoid totally adhoc overriding (see also Build_Process.progress vs. build_progress);
wenzelm
parents: 77504
diff changeset
   220
    enabled: Boolean = true
77509
3bc49507bae5 clarified treatment of "verbose" messages, e.g. Progress.theory();
wenzelm
parents: 77507
diff changeset
   221
  ): A = Timing.timeit(body, message = message, enabled = enabled, output = echo(_))
65921
5b42937d3b2d more operations;
wenzelm
parents: 65910
diff changeset
   222
77524
a3dda42cd110 more robust: disallow override;
wenzelm
parents: 77509
diff changeset
   223
  @volatile private var is_stopped = false
73367
77ef8bef0593 clarified signature --- fewer warnings;
wenzelm
parents: 73340
diff changeset
   224
  def stop(): Unit = { is_stopped = true }
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73897
diff changeset
   225
  def stopped: Boolean = {
73367
77ef8bef0593 clarified signature --- fewer warnings;
wenzelm
parents: 73340
diff changeset
   226
    if (Thread.interrupted()) is_stopped = true
71726
a5fda30edae2 clarified signature: more uniform treatment of stopped/interrupted state;
wenzelm
parents: 71601
diff changeset
   227
    is_stopped
a5fda30edae2 clarified signature: more uniform treatment of stopped/interrupted state;
wenzelm
parents: 71601
diff changeset
   228
  }
a5fda30edae2 clarified signature: more uniform treatment of stopped/interrupted state;
wenzelm
parents: 71601
diff changeset
   229
77506
a8175b950173 more robust signature: avoid totally adhoc overriding (see also Build_Process.progress vs. build_progress);
wenzelm
parents: 77504
diff changeset
   230
  final def interrupt_handler[A](e: => A): A = POSIX_Interrupt.handler { stop() } { e }
a8175b950173 more robust signature: avoid totally adhoc overriding (see also Build_Process.progress vs. build_progress);
wenzelm
parents: 77504
diff changeset
   231
  final def expose_interrupt(): Unit = if (stopped) throw Exn.Interrupt()
61276
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
   232
  override def toString: String = if (stopped) "Progress(stopped)" else "Progress"
64201
wenzelm
parents: 64117
diff changeset
   233
77506
a8175b950173 more robust signature: avoid totally adhoc overriding (see also Build_Process.progress vs. build_progress);
wenzelm
parents: 77504
diff changeset
   234
  final def bash(script: String,
80230
cb4b21b7b473 support bash via SSH;
wenzelm
parents: 80225
diff changeset
   235
    ssh: SSH.System = SSH.Local,
80224
db92e0b6a11a clarified signature: prefer symbolic isabelle.Path over physical java.io.File;
wenzelm
parents: 79887
diff changeset
   236
    cwd: Path = Path.current,
82706
e9b9af6da795 clarified signature;
wenzelm
parents: 80236
diff changeset
   237
    env: JMap[String, String] = Isabelle_System.Settings.env(),  // ignored for remote ssh
64201
wenzelm
parents: 64117
diff changeset
   238
    redirect: Boolean = false,
65930
9a28fc03c3fe tuned signature;
wenzelm
parents: 65921
diff changeset
   239
    echo: Boolean = false,
80236
c6670f9575de clarified signature;
wenzelm
parents: 80235
diff changeset
   240
    watchdog_time: Time = Time.zero,
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73897
diff changeset
   241
    strict: Boolean = true
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73897
diff changeset
   242
  ): Process_Result = {
72599
76550282267f more interrupts, notably for running latex;
wenzelm
parents: 72574
diff changeset
   243
    val result =
80230
cb4b21b7b473 support bash via SSH;
wenzelm
parents: 80225
diff changeset
   244
      Isabelle_System.bash(script, ssh = ssh, cwd = cwd, env = env, redirect = redirect,
72599
76550282267f more interrupts, notably for running latex;
wenzelm
parents: 72574
diff changeset
   245
        progress_stdout = echo_if(echo, _),
76550282267f more interrupts, notably for running latex;
wenzelm
parents: 72574
diff changeset
   246
        progress_stderr = echo_if(echo, _),
80236
c6670f9575de clarified signature;
wenzelm
parents: 80235
diff changeset
   247
        watchdog = Bash.Watchdog(watchdog_time, _ => stopped),
72599
76550282267f more interrupts, notably for running latex;
wenzelm
parents: 72574
diff changeset
   248
        strict = strict)
76550282267f more interrupts, notably for running latex;
wenzelm
parents: 72574
diff changeset
   249
    if (strict && stopped) throw Exn.Interrupt() else result
64201
wenzelm
parents: 64117
diff changeset
   250
  }
61276
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
   251
}
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
   252
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   253
class Console_Progress(
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   254
  override val verbose: Boolean = false,
83507
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   255
  threshold: Time = Time.zero,
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   256
  detailed: Boolean = false,
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   257
  stderr: Boolean = false)
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   258
extends Progress with Progress.Status {
83507
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   259
  override def status_threshold: Time = threshold
83280
a3c59c842625 clarified signature;
wenzelm
parents: 83271
diff changeset
   260
  override def status_detailed: Boolean = detailed
83507
989304e45ad7 progress for long-running commands;
wenzelm
parents: 83315
diff changeset
   261
83271
93db1865ee0e clarified Progress.Status: more general types;
wenzelm
parents: 83270
diff changeset
   262
  override def status_hide(status: Progress.Output): Unit = synchronized {
93db1865ee0e clarified Progress.Status: more general types;
wenzelm
parents: 83270
diff changeset
   263
    val txt = output_text(status, terminate = true)
93db1865ee0e clarified Progress.Status: more general types;
wenzelm
parents: 83270
diff changeset
   264
    Output.delete_lines(Library.count_newlines(txt), stdout = !stderr)
83266
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   265
  }
2f75f2495e3e more detailed Console_Progress via Progress.Status;
wenzelm
parents: 83229
diff changeset
   266
83286
f772c9234f7f proper status_output for output via Progress.Status mixin;
wenzelm
parents: 83285
diff changeset
   267
  override def status_output(msgs: Progress.Output): Unit = synchronized {
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   268
    for (msg <- msgs if do_output(msg)) {
83290
10d6a6d43599 clarified console output;
wenzelm
parents: 83289
diff changeset
   269
      val txt0 = msg.message.output_text
83306
2616fa68b9c6 more robust reset of console text styles, notably for Windows/Cygwin;
wenzelm
parents: 83304
diff changeset
   270
      val txt1 = if (msg.status) "\u001b[7m" + txt0 + "\u001b[0m" else txt0
83290
10d6a6d43599 clarified console output;
wenzelm
parents: 83289
diff changeset
   271
      Output.output(txt1, stdout = !stderr, include_empty = true)
77509
3bc49507bae5 clarified treatment of "verbose" messages, e.g. Progress.theory();
wenzelm
parents: 77507
diff changeset
   272
    }
78874
162ce304955e more robust: support concurrent output;
wenzelm
parents: 78611
diff changeset
   273
  }
77503
daf632e9ce7e tuned messages;
wenzelm
parents: 77502
diff changeset
   274
daf632e9ce7e tuned messages;
wenzelm
parents: 77502
diff changeset
   275
  override def toString: String = super.toString + ": console"
61276
8a4bd05c1735 clarified modules;
wenzelm
parents:
diff changeset
   276
}
65888
29a31cf0b4bc more Progress variations;
wenzelm
parents: 65828
diff changeset
   277
77507
8dfe2fbc98e7 tuned whitespace;
wenzelm
parents: 77506
diff changeset
   278
class File_Progress(path: Path, override val verbose: Boolean = false)
83282
4643bb10d188 verbose output of completed theories;
wenzelm
parents: 83280
diff changeset
   279
extends Progress with Progress.Status {
83286
f772c9234f7f proper status_output for output via Progress.Status mixin;
wenzelm
parents: 83285
diff changeset
   280
  override def status_output(msgs: Progress.Output): Unit = synchronized {
83269
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   281
    val txt = output_text(msgs, terminate = true)
f6de20fbf55f clarified Progress.output and related operations: prefer bulk messages of general type Progress.Msg;
wenzelm
parents: 83266
diff changeset
   282
    if (txt.nonEmpty) File.append(path, txt)
78874
162ce304955e more robust: support concurrent output;
wenzelm
parents: 78611
diff changeset
   283
  }
65888
29a31cf0b4bc more Progress variations;
wenzelm
parents: 65828
diff changeset
   284
77503
daf632e9ce7e tuned messages;
wenzelm
parents: 77502
diff changeset
   285
  override def toString: String = super.toString + ": " + path.toString
65888
29a31cf0b4bc more Progress variations;
wenzelm
parents: 65828
diff changeset
   286
}