| author | wenzelm | 
| Fri, 25 Aug 2023 13:56:00 +0200 | |
| changeset 78575 | ff86f10e54cd | 
| parent 78574 | 06e045375487 | 
| child 78577 | a945b541efff | 
| permissions | -rw-r--r-- | 
| 77238 | 1  | 
/* Title: Pure/Tools/build_process.scala  | 
2  | 
Author: Makarius  | 
|
3  | 
||
4  | 
Build process for sessions, with build database, optional heap, and  | 
|
5  | 
optional presentation.  | 
|
6  | 
*/  | 
|
7  | 
||
8  | 
package isabelle  | 
|
9  | 
||
10  | 
||
| 77505 | 11  | 
import scala.collection.immutable.SortedMap  | 
| 77246 | 12  | 
import scala.math.Ordering  | 
| 77257 | 13  | 
import scala.annotation.tailrec  | 
| 77246 | 14  | 
|
15  | 
||
| 77238 | 16  | 
object Build_Process {
 | 
| 78421 | 17  | 
/** state vs. database **/  | 
| 77257 | 18  | 
|
| 78238 | 19  | 
sealed case class Build(  | 
| 78173 | 20  | 
build_uuid: String, // Database_Progress.context_uuid  | 
| 77660 | 21  | 
ml_platform: String,  | 
22  | 
options: String,  | 
|
23  | 
start: Date,  | 
|
| 78226 | 24  | 
stop: Option[Date],  | 
25  | 
sessions: List[String]  | 
|
| 78222 | 26  | 
  ) {
 | 
27  | 
def active: Boolean = stop.isEmpty  | 
|
28  | 
}  | 
|
| 77660 | 29  | 
|
| 78238 | 30  | 
sealed case class Worker(  | 
| 78173 | 31  | 
worker_uuid: String, // Database_Progress.agent_uuid  | 
| 77631 | 32  | 
build_uuid: String,  | 
33  | 
start: Date,  | 
|
34  | 
stamp: Date,  | 
|
35  | 
stop: Option[Date],  | 
|
36  | 
serial: Long  | 
|
37  | 
)  | 
|
38  | 
||
| 78238 | 39  | 
sealed case class Task(  | 
| 77631 | 40  | 
name: String,  | 
41  | 
deps: List[String],  | 
|
| 
77661
 
45bd5c26cbcc
proper build_uuid for Build_Process.Task: thus old entries are removed via prepare_database/clean_build;
 
wenzelm 
parents: 
77660 
diff
changeset
 | 
42  | 
info: JSON.Object.T,  | 
| 
 
45bd5c26cbcc
proper build_uuid for Build_Process.Task: thus old entries are removed via prepare_database/clean_build;
 
wenzelm 
parents: 
77660 
diff
changeset
 | 
43  | 
build_uuid: String  | 
| 77631 | 44  | 
  ) {
 | 
| 
77313
 
f8aa1647d156
more elementary data structures, to fit better to SQL database;
 
wenzelm 
parents: 
77312 
diff
changeset
 | 
45  | 
def is_ready: Boolean = deps.isEmpty  | 
| 77585 | 46  | 
def resolve(dep: String): Task =  | 
| 
77313
 
f8aa1647d156
more elementary data structures, to fit better to SQL database;
 
wenzelm 
parents: 
77312 
diff
changeset
 | 
47  | 
if (deps.contains(dep)) copy(deps = deps.filterNot(_ == dep)) else this  | 
| 
 
f8aa1647d156
more elementary data structures, to fit better to SQL database;
 
wenzelm 
parents: 
77312 
diff
changeset
 | 
48  | 
}  | 
| 
 
f8aa1647d156
more elementary data structures, to fit better to SQL database;
 
wenzelm 
parents: 
77312 
diff
changeset
 | 
49  | 
|
| 78238 | 50  | 
sealed case class Job(  | 
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
51  | 
name: String,  | 
| 
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
52  | 
worker_uuid: String,  | 
| 77634 | 53  | 
build_uuid: String,  | 
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
54  | 
node_info: Host.Node_Info,  | 
| 
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
55  | 
build: Option[Build_Job]  | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
56  | 
  ) extends Library.Named {
 | 
| 78530 | 57  | 
def join_build: Option[Build_Job.Result] = build.flatMap(_.join)  | 
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
58  | 
}  | 
| 
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
59  | 
|
| 78238 | 60  | 
sealed case class Result(  | 
| 77651 | 61  | 
name: String,  | 
62  | 
worker_uuid: String,  | 
|
63  | 
build_uuid: String,  | 
|
64  | 
node_info: Host.Node_Info,  | 
|
| 77461 | 65  | 
process_result: Process_Result,  | 
| 
77460
 
ccca589d7027
tuned signature: support general Build_Job instances;
 
wenzelm 
parents: 
77459 
diff
changeset
 | 
66  | 
output_shasum: SHA1.Shasum,  | 
| 77461 | 67  | 
current: Boolean  | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
68  | 
  ) extends Library.Named {
 | 
| 
77259
 
61fc2afe4c8b
clarified signature: prefer stateful object-oriented style, to make it fit better into physical world;
 
wenzelm 
parents: 
77258 
diff
changeset
 | 
69  | 
def ok: Boolean = process_result.ok  | 
| 
 
61fc2afe4c8b
clarified signature: prefer stateful object-oriented style, to make it fit better into physical world;
 
wenzelm 
parents: 
77258 
diff
changeset
 | 
70  | 
}  | 
| 77312 | 71  | 
|
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
72  | 
  object Sessions {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
73  | 
type Graph = isabelle.Graph[String, Build_Job.Session_Context]  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
74  | 
val empty: Sessions = new Sessions(Graph.string)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
75  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
76  | 
|
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
77  | 
  final class Sessions private(val graph: Sessions.Graph) {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
78  | 
override def toString: String = graph.toString  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
79  | 
|
| 
78500
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
80  | 
def defined(name: String): Boolean = graph.defined(name)  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
81  | 
def apply(name: String): Build_Job.Session_Context = graph.get_node(name)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
82  | 
|
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
83  | 
def iterator: Iterator[Build_Job.Session_Context] =  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
84  | 
for (name <- graph.topological_order.iterator) yield apply(name)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
85  | 
|
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
86  | 
def make(new_graph: Sessions.Graph): Sessions =  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
87  | 
if (graph == new_graph) this  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
88  | 
      else {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
89  | 
new Sessions(  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
90  | 
          new_graph.iterator.foldLeft(new_graph) {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
91  | 
case (g, (name, (session, _))) => g.add_deps_acyclic(name, session.deps)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
92  | 
})  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
93  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
94  | 
|
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
95  | 
def pull(  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
96  | 
data_domain: Set[String],  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
97  | 
data: Set[String] => List[Build_Job.Session_Context]  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
98  | 
    ): Sessions = {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
99  | 
val dom = data_domain -- iterator.map(_.name)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
100  | 
      make(data(dom).foldLeft(graph.restrict(dom)) { case (g, e) => g.new_node(e.name, e) })
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
101  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
102  | 
|
| 78372 | 103  | 
def init(  | 
| 78421 | 104  | 
build_context: isabelle.Build.Context,  | 
| 78374 | 105  | 
database_server: Option[SQL.Database],  | 
106  | 
progress: Progress = new Progress  | 
|
| 78372 | 107  | 
    ): Sessions = {
 | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
108  | 
val sessions_structure = build_context.sessions_structure  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
109  | 
make(  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
110  | 
        sessions_structure.build_graph.iterator.foldLeft(graph) {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
111  | 
case (graph0, (name, (info, _))) =>  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
112  | 
val deps = info.parent.toList  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
113  | 
val prefs = info.session_prefs  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
114  | 
val ancestors = sessions_structure.build_requirements(deps)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
115  | 
val sources_shasum = build_context.build_deps.sources_shasum(name)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
116  | 
|
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
117  | 
            if (graph0.defined(name)) {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
118  | 
val session0 = graph0.get_node(name)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
119  | 
val prefs0 = session0.session_prefs  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
120  | 
val ancestors0 = session0.ancestors  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
121  | 
val sources_shasum0 = session0.sources_shasum  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
122  | 
|
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
123  | 
def err(msg: String, a: String, b: String): Nothing =  | 
| 78501 | 124  | 
                error("Conflicting dependencies for session " + quote(name) + ": " + msg + "\n" +
 | 
125  | 
Library.indent_lines(2, a) + "\nvs.\n" + Library.indent_lines(2, b))  | 
|
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
126  | 
|
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
127  | 
              if (prefs0 != prefs) {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
128  | 
                err("preferences disagree",
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
129  | 
Symbol.cartouche_decoded(prefs0), Symbol.cartouche_decoded(prefs))  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
130  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
131  | 
              if (ancestors0 != ancestors) {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
132  | 
                err("ancestors disagree", commas_quote(ancestors0), commas_quote(ancestors))
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
133  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
134  | 
              if (sources_shasum0 != sources_shasum) {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
135  | 
val a = sources_shasum0 - sources_shasum  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
136  | 
val b = sources_shasum - sources_shasum0  | 
| 78501 | 137  | 
                err("sources disagree",
 | 
138  | 
Library.trim_line(a.toString),  | 
|
139  | 
Library.trim_line(b.toString))  | 
|
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
140  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
141  | 
|
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
142  | 
graph0  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
143  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
144  | 
            else {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
145  | 
val session =  | 
| 78374 | 146  | 
Build_Job.Session_Context.load(database_server,  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
147  | 
build_context.build_uuid, name, deps, ancestors, prefs, sources_shasum,  | 
| 78374 | 148  | 
info.timeout, build_context.store, progress = progress)  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
149  | 
graph0.new_node(name, session)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
150  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
151  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
152  | 
)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
153  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
154  | 
|
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
155  | 
    lazy val max_time: Map[String, Double] = {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
156  | 
val maximals = graph.maximals.toSet  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
157  | 
      def descendants_time(name: String): Double = {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
158  | 
if (maximals.contains(name)) apply(name).old_time.seconds  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
159  | 
        else {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
160  | 
val descendants = graph.all_succs(List(name)).toSet  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
161  | 
val g = graph.restrict(descendants)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
162  | 
          (0.0 :: g.maximals.flatMap { desc =>
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
163  | 
val ps = g.all_preds(List(desc))  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
164  | 
if (ps.exists(p => !graph.defined(p))) None  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
165  | 
else Some(ps.map(p => apply(p).old_time.seconds).sum)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
166  | 
}).max  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
167  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
168  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
169  | 
Map.from(  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
170  | 
for (name <- graph.keys_iterator)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
171  | 
yield name -> descendants_time(name)).withDefaultValue(0.0)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
172  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
173  | 
|
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
174  | 
lazy val ordering: Ordering[String] =  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
175  | 
(a: String, b: String) =>  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
176  | 
        max_time(b) compare max_time(a) match {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
177  | 
case 0 =>  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
178  | 
            apply(b).timeout compare apply(a).timeout match {
 | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
179  | 
case 0 => a compare b  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
180  | 
case ord => ord  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
181  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
182  | 
case ord => ord  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
183  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
184  | 
}  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
185  | 
|
| 
77659
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
186  | 
sealed case class Snapshot(  | 
| 77660 | 187  | 
builds: List[Build], // available build configurations  | 
| 
77659
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
188  | 
workers: List[Worker], // available worker processes  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
189  | 
sessions: Sessions, // static build targets  | 
| 
77659
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
190  | 
pending: State.Pending, // dynamic build "queue"  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
191  | 
running: State.Running, // presently running jobs  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
192  | 
results: State.Results) // finished results  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
193  | 
|
| 77496 | 194  | 
  object State {
 | 
| 77585 | 195  | 
type Pending = List[Task]  | 
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
196  | 
type Running = Map[String, Job]  | 
| 77496 | 197  | 
type Results = Map[String, Result]  | 
198  | 
}  | 
|
199  | 
||
| 
77334
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
200  | 
sealed case class State(  | 
| 77372 | 201  | 
serial: Long = 0,  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
202  | 
numa_nodes: List[Int] = Nil,  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
203  | 
sessions: Sessions = Sessions.empty,  | 
| 
77659
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
204  | 
pending: State.Pending = Nil,  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
205  | 
running: State.Running = Map.empty,  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
206  | 
results: State.Results = Map.empty  | 
| 
77334
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
207  | 
  ) {
 | 
| 77513 | 208  | 
require(serial >= 0, "serial underflow")  | 
| 78574 | 209  | 
    def inc_serial: State = {
 | 
210  | 
require(serial < Long.MaxValue, "serial overflow")  | 
|
211  | 
copy(serial = serial + 1)  | 
|
| 77513 | 212  | 
}  | 
213  | 
||
| 
77334
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
214  | 
def remove_pending(name: String): State =  | 
| 
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
215  | 
copy(pending = pending.flatMap(  | 
| 
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
216  | 
entry => if (entry.name == name) None else Some(entry.resolve(name))))  | 
| 
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
217  | 
|
| 
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
218  | 
def is_running(name: String): Boolean = running.isDefinedAt(name)  | 
| 
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
219  | 
|
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
220  | 
def stop_running(): Unit =  | 
| 
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
221  | 
for (job <- running.valuesIterator; build <- job.build) build.cancel()  | 
| 
77334
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
222  | 
|
| 
78529
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
223  | 
def build_running: List[Build_Job] =  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
224  | 
List.from(for (job <- running.valuesIterator; build <- job.build) yield build)  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
225  | 
|
| 77649 | 226  | 
def finished_running(): List[Job] =  | 
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
227  | 
List.from(  | 
| 
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
228  | 
for (job <- running.valuesIterator; build <- job.build if build.is_finished)  | 
| 
78529
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
229  | 
yield job)  | 
| 
77334
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
230  | 
|
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
231  | 
def add_running(job: Job): State =  | 
| 
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
232  | 
copy(running = running + (job.name -> job))  | 
| 
77334
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
233  | 
|
| 
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
234  | 
def remove_running(name: String): State =  | 
| 
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
235  | 
copy(running = running - name)  | 
| 
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
236  | 
|
| 77336 | 237  | 
def make_result(  | 
| 77651 | 238  | 
result_name: (String, String, String),  | 
| 77461 | 239  | 
process_result: Process_Result,  | 
| 
77460
 
ccca589d7027
tuned signature: support general Build_Job instances;
 
wenzelm 
parents: 
77459 
diff
changeset
 | 
240  | 
output_shasum: SHA1.Shasum,  | 
| 77475 | 241  | 
node_info: Host.Node_Info = Host.Node_Info.none,  | 
| 77461 | 242  | 
current: Boolean = false  | 
| 
77334
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
243  | 
    ): State = {
 | 
| 77651 | 244  | 
val (name, worker_uuid, build_uuid) = result_name  | 
245  | 
val result =  | 
|
246  | 
Result(name, worker_uuid, build_uuid, node_info, process_result, output_shasum, current)  | 
|
247  | 
copy(results = results + (name -> result))  | 
|
| 
77334
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
248  | 
}  | 
| 
78500
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
249  | 
|
| 
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
250  | 
    def ancestor_results(name: String): Option[List[Result]] = {
 | 
| 
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
251  | 
val defined =  | 
| 
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
252  | 
sessions.defined(name) &&  | 
| 
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
253  | 
sessions(name).ancestors.forall(a => sessions.defined(a) && results.isDefinedAt(a))  | 
| 
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
254  | 
if (defined) Some(sessions(name).ancestors.map(results)) else None  | 
| 
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
255  | 
}  | 
| 
77334
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
256  | 
}  | 
| 
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
257  | 
|
| 
 
0231e62956a6
clarified state: more explicit type as plain value, which is also easier to sync with external db;
 
wenzelm 
parents: 
77333 
diff
changeset
 | 
258  | 
|
| 77436 | 259  | 
|
260  | 
/** SQL data model **/  | 
|
| 77372 | 261  | 
|
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
262  | 
  object private_data extends SQL.Data("isabelle_build") {
 | 
| 78168 | 263  | 
    val database: Path = Path.explode("$ISABELLE_HOME_USER/build.db")
 | 
264  | 
||
| 78244 | 265  | 
def pull[A <: Library.Named](  | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
266  | 
data_domain: Set[String],  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
267  | 
data_iterator: Set[String] => Iterator[A],  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
268  | 
old_data: Map[String, A]  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
269  | 
    ): Map[String, A] = {
 | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
270  | 
val dom = data_domain -- old_data.keysIterator  | 
| 78268 | 271  | 
val data = old_data -- old_data.keysIterator.filterNot(data_domain)  | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
272  | 
if (dom.isEmpty) data  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
273  | 
      else data_iterator(dom).foldLeft(data) { case (map, a) => map + (a.name -> a) }
 | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
274  | 
}  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
275  | 
|
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
276  | 
def pull0[A <: Library.Named](  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
277  | 
new_data: Map[String, A],  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
278  | 
old_data: Map[String, A]  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
279  | 
    ): Map[String, A] = {
 | 
| 78244 | 280  | 
pull(new_data.keySet, dom => new_data.valuesIterator.filter(a => dom(a.name)), old_data)  | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
281  | 
}  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
282  | 
|
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
283  | 
def pull1[A <: Library.Named](  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
284  | 
data_domain: Set[String],  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
285  | 
data_base: Set[String] => Map[String, A],  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
286  | 
old_data: Map[String, A]  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
287  | 
    ): Map[String, A] = {
 | 
| 78244 | 288  | 
pull(data_domain, dom => data_base(dom).valuesIterator, old_data)  | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
289  | 
}  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
290  | 
|
| 77372 | 291  | 
    object Generic {
 | 
| 
77529
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
292  | 
      val build_uuid = SQL.Column.string("build_uuid")
 | 
| 
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
293  | 
      val worker_uuid = SQL.Column.string("worker_uuid")
 | 
| 77372 | 294  | 
      val name = SQL.Column.string("name")
 | 
295  | 
||
| 
77529
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
296  | 
def sql(  | 
| 
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
297  | 
build_uuid: String = "",  | 
| 
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
298  | 
worker_uuid: String = "",  | 
| 
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
299  | 
names: Iterable[String] = Nil  | 
| 
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
300  | 
): SQL.Source =  | 
| 77372 | 301  | 
SQL.and(  | 
| 
77529
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
302  | 
if_proper(build_uuid, Generic.build_uuid.equal(build_uuid)),  | 
| 
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
303  | 
if_proper(worker_uuid, Generic.worker_uuid.equal(worker_uuid)),  | 
| 77375 | 304  | 
if_proper(names, Generic.name.member(names)))  | 
| 77662 | 305  | 
|
306  | 
def sql_where(  | 
|
307  | 
build_uuid: String = "",  | 
|
308  | 
worker_uuid: String = "",  | 
|
309  | 
names: Iterable[String] = Nil  | 
|
310  | 
      ): SQL.Source = {
 | 
|
| 77663 | 311  | 
SQL.where(sql(build_uuid = build_uuid, worker_uuid = worker_uuid, names = names))  | 
| 77662 | 312  | 
}  | 
| 77372 | 313  | 
}  | 
314  | 
||
| 
77536
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
315  | 
|
| 
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
316  | 
/* base table */  | 
| 
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
317  | 
|
| 77417 | 318  | 
    object Base {
 | 
| 
77529
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
319  | 
val build_uuid = Generic.build_uuid.make_primary_key  | 
| 
77387
 
cd10b8edfdf5
clarified db content: avoid redundancy of historic ML_IDENTIFIER;
 
wenzelm 
parents: 
77385 
diff
changeset
 | 
320  | 
      val ml_platform = SQL.Column.string("ml_platform")
 | 
| 77372 | 321  | 
      val options = SQL.Column.string("options")
 | 
| 
77536
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
322  | 
      val start = SQL.Column.date("start")
 | 
| 77545 | 323  | 
      val stop = SQL.Column.date("stop")
 | 
| 77372 | 324  | 
|
| 78266 | 325  | 
val table = make_table(List(build_uuid, ml_platform, options, start, stop))  | 
| 
77536
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
326  | 
}  | 
| 
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
327  | 
|
| 78226 | 328  | 
    def read_builds(db: SQL.Database, build_uuid: String = ""): List[Build] = {
 | 
329  | 
val builds =  | 
|
330  | 
db.execute_query_statement(  | 
|
331  | 
Base.table.select(sql = Generic.sql_where(build_uuid = build_uuid)),  | 
|
332  | 
List.from[Build],  | 
|
333  | 
          { res =>
 | 
|
334  | 
val build_uuid = res.string(Base.build_uuid)  | 
|
335  | 
val ml_platform = res.string(Base.ml_platform)  | 
|
336  | 
val options = res.string(Base.options)  | 
|
337  | 
val start = res.date(Base.start)  | 
|
338  | 
val stop = res.get_date(Base.stop)  | 
|
339  | 
Build(build_uuid, ml_platform, options, start, stop, Nil)  | 
|
340  | 
})  | 
|
341  | 
||
342  | 
      for (build <- builds.sortBy(_.start)(Date.Ordering)) yield {
 | 
|
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
343  | 
val sessions = private_data.read_sessions_domain(db, build_uuid = build.build_uuid)  | 
| 78226 | 344  | 
build.copy(sessions = sessions.toList.sorted)  | 
345  | 
}  | 
|
346  | 
}  | 
|
| 77660 | 347  | 
|
| 
77536
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
348  | 
def start_build(  | 
| 
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
349  | 
db: SQL.Database,  | 
| 
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
350  | 
build_uuid: String,  | 
| 
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
351  | 
ml_platform: String,  | 
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
352  | 
options: String  | 
| 
77536
 
7c7f1473e51a
clarified database content and prepare/init stages;
 
wenzelm 
parents: 
77534 
diff
changeset
 | 
353  | 
    ): Unit = {
 | 
| 77541 | 354  | 
db.execute_statement(Base.table.insert(), body =  | 
355  | 
        { stmt =>
 | 
|
356  | 
stmt.string(1) = build_uuid  | 
|
357  | 
stmt.string(2) = ml_platform  | 
|
358  | 
stmt.string(3) = options  | 
|
359  | 
stmt.date(4) = db.now()  | 
|
360  | 
stmt.date(5) = None  | 
|
361  | 
})  | 
|
| 77372 | 362  | 
}  | 
363  | 
||
| 77545 | 364  | 
def stop_build(db: SQL.Database, build_uuid: String): Unit =  | 
| 77541 | 365  | 
db.execute_statement(  | 
| 77636 | 366  | 
Base.table.update(List(Base.stop), sql = Base.build_uuid.where_equal(build_uuid)),  | 
| 77541 | 367  | 
        body = { stmt => stmt.date(1) = db.now() })
 | 
| 77538 | 368  | 
|
| 
77539
 
2b996a0df1ce
proper clean_build of old data at start of new process --- allow to inspect remains of the last process;
 
wenzelm 
parents: 
77538 
diff
changeset
 | 
369  | 
    def clean_build(db: SQL.Database): Unit = {
 | 
| 
 
2b996a0df1ce
proper clean_build of old data at start of new process --- allow to inspect remains of the last process;
 
wenzelm 
parents: 
77538 
diff
changeset
 | 
370  | 
val old =  | 
| 77552 | 371  | 
db.execute_query_statement(  | 
372  | 
Base.table.select(List(Base.build_uuid), sql = SQL.where(Base.stop.defined)),  | 
|
373  | 
List.from[String], res => res.string(Base.build_uuid))  | 
|
| 
77539
 
2b996a0df1ce
proper clean_build of old data at start of new process --- allow to inspect remains of the last process;
 
wenzelm 
parents: 
77538 
diff
changeset
 | 
374  | 
|
| 
 
2b996a0df1ce
proper clean_build of old data at start of new process --- allow to inspect remains of the last process;
 
wenzelm 
parents: 
77538 
diff
changeset
 | 
375  | 
      if (old.nonEmpty) {
 | 
| 
78545
 
5f4ca329fde4
minor performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78536 
diff
changeset
 | 
376  | 
val sql = Generic.build_uuid.where_member(old)  | 
| 
 
5f4ca329fde4
minor performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78536 
diff
changeset
 | 
377  | 
db.execute_statement(SQL.MULTI(build_uuid_tables.map(_.delete(sql = sql))))  | 
| 
77539
 
2b996a0df1ce
proper clean_build of old data at start of new process --- allow to inspect remains of the last process;
 
wenzelm 
parents: 
77538 
diff
changeset
 | 
378  | 
}  | 
| 
 
2b996a0df1ce
proper clean_build of old data at start of new process --- allow to inspect remains of the last process;
 
wenzelm 
parents: 
77538 
diff
changeset
 | 
379  | 
}  | 
| 
 
2b996a0df1ce
proper clean_build of old data at start of new process --- allow to inspect remains of the last process;
 
wenzelm 
parents: 
77538 
diff
changeset
 | 
380  | 
|
| 
77416
 
d88c12f22ab0
clarified scope of "serial" and "numa_index" within database;
 
wenzelm 
parents: 
77415 
diff
changeset
 | 
381  | 
|
| 77531 | 382  | 
/* sessions */  | 
| 77505 | 383  | 
|
| 77496 | 384  | 
    object Sessions {
 | 
385  | 
val name = Generic.name.make_primary_key  | 
|
386  | 
      val deps = SQL.Column.string("deps")
 | 
|
387  | 
      val ancestors = SQL.Column.string("ancestors")
 | 
|
| 
77610
 
3b09ae9e40cb
clarified session prefs (or "options" within the database);
 
wenzelm 
parents: 
77609 
diff
changeset
 | 
388  | 
      val options = SQL.Column.string("options")
 | 
| 77496 | 389  | 
      val sources = SQL.Column.string("sources")
 | 
390  | 
      val timeout = SQL.Column.long("timeout")
 | 
|
391  | 
      val old_time = SQL.Column.long("old_time")
 | 
|
392  | 
      val old_command_timings = SQL.Column.bytes("old_command_timings")
 | 
|
| 
77529
 
40ccee0fe19a
separate static build_uuid from dynamic worker_uuid, to allow multiple worker processes participate in one build process;
 
wenzelm 
parents: 
77527 
diff
changeset
 | 
393  | 
val build_uuid = Generic.build_uuid  | 
| 77496 | 394  | 
|
| 78266 | 395  | 
val table =  | 
396  | 
make_table(  | 
|
397  | 
List(name, deps, ancestors, options, sources, timeout,  | 
|
398  | 
old_time, old_command_timings, build_uuid),  | 
|
399  | 
name = "sessions")  | 
|
| 77496 | 400  | 
}  | 
401  | 
||
| 
78218
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
402  | 
def read_sessions_domain(db: SQL.Database, build_uuid: String = ""): Set[String] =  | 
| 77552 | 403  | 
db.execute_query_statement(  | 
| 
78218
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
404  | 
Sessions.table.select(List(Sessions.name),  | 
| 78251 | 405  | 
sql = if_proper(build_uuid, Sessions.build_uuid.where_equal(build_uuid))),  | 
| 77552 | 406  | 
Set.from[String], res => res.string(Sessions.name))  | 
| 77496 | 407  | 
|
| 
78218
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
408  | 
def read_sessions(db: SQL.Database,  | 
| 
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
409  | 
names: Iterable[String] = Nil,  | 
| 
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
410  | 
build_uuid: String = ""  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
411  | 
    ): List[Build_Job.Session_Context] = {
 | 
| 77552 | 412  | 
db.execute_query_statement(  | 
| 
78218
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
413  | 
Sessions.table.select(  | 
| 
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
414  | 
sql =  | 
| 
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
415  | 
SQL.where_and(  | 
| 
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
416  | 
if_proper(names, Sessions.name.member(names)),  | 
| 
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
417  | 
if_proper(build_uuid, Sessions.build_uuid.equal(build_uuid)))  | 
| 
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
418  | 
),  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
419  | 
List.from[Build_Job.Session_Context],  | 
| 77552 | 420  | 
        { res =>
 | 
421  | 
val name = res.string(Sessions.name)  | 
|
422  | 
val deps = split_lines(res.string(Sessions.deps))  | 
|
423  | 
val ancestors = split_lines(res.string(Sessions.ancestors))  | 
|
| 
77610
 
3b09ae9e40cb
clarified session prefs (or "options" within the database);
 
wenzelm 
parents: 
77609 
diff
changeset
 | 
424  | 
val options = res.string(Sessions.options)  | 
| 77552 | 425  | 
val sources_shasum = SHA1.fake_shasum(res.string(Sessions.sources))  | 
426  | 
val timeout = Time.ms(res.long(Sessions.timeout))  | 
|
427  | 
val old_time = Time.ms(res.long(Sessions.old_time))  | 
|
428  | 
val old_command_timings_blob = res.bytes(Sessions.old_command_timings)  | 
|
429  | 
val build_uuid = res.string(Sessions.build_uuid)  | 
|
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
430  | 
Build_Job.Session_Context(name, deps, ancestors, options, sources_shasum,  | 
| 77552 | 431  | 
timeout, old_time, old_command_timings_blob, build_uuid)  | 
| 77496 | 432  | 
}  | 
| 77552 | 433  | 
)  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
434  | 
}  | 
| 77496 | 435  | 
|
| 78553 | 436  | 
def update_sessions(  | 
437  | 
db: SQL.Database,  | 
|
438  | 
sessions: Build_Process.Sessions,  | 
|
439  | 
old_sessions: Build_Process.Sessions  | 
|
440  | 
    ): Boolean = {
 | 
|
441  | 
val insert = sessions.iterator.filterNot(s => old_sessions.defined(s.name)).toList  | 
|
| 77496 | 442  | 
|
| 
78552
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
443  | 
      if (insert.nonEmpty) {
 | 
| 
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
444  | 
db.execute_batch_statement(Sessions.table.insert(), batch =  | 
| 
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
445  | 
          for (session <- insert) yield { (stmt: SQL.Statement) =>
 | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
446  | 
stmt.string(1) = session.name  | 
| 77541 | 447  | 
stmt.string(2) = cat_lines(session.deps)  | 
448  | 
stmt.string(3) = cat_lines(session.ancestors)  | 
|
| 
77610
 
3b09ae9e40cb
clarified session prefs (or "options" within the database);
 
wenzelm 
parents: 
77609 
diff
changeset
 | 
449  | 
stmt.string(4) = session.session_prefs  | 
| 
 
3b09ae9e40cb
clarified session prefs (or "options" within the database);
 
wenzelm 
parents: 
77609 
diff
changeset
 | 
450  | 
stmt.string(5) = session.sources_shasum.toString  | 
| 
 
3b09ae9e40cb
clarified session prefs (or "options" within the database);
 
wenzelm 
parents: 
77609 
diff
changeset
 | 
451  | 
stmt.long(6) = session.timeout.ms  | 
| 
 
3b09ae9e40cb
clarified session prefs (or "options" within the database);
 
wenzelm 
parents: 
77609 
diff
changeset
 | 
452  | 
stmt.long(7) = session.old_time.ms  | 
| 
 
3b09ae9e40cb
clarified session prefs (or "options" within the database);
 
wenzelm 
parents: 
77609 
diff
changeset
 | 
453  | 
stmt.bytes(8) = session.old_command_timings_blob  | 
| 
 
3b09ae9e40cb
clarified session prefs (or "options" within the database);
 
wenzelm 
parents: 
77609 
diff
changeset
 | 
454  | 
stmt.string(9) = session.build_uuid  | 
| 77541 | 455  | 
})  | 
| 77496 | 456  | 
}  | 
457  | 
||
458  | 
insert.nonEmpty  | 
|
459  | 
}  | 
|
460  | 
||
| 77531 | 461  | 
|
462  | 
/* workers */  | 
|
463  | 
||
464  | 
    object Workers {
 | 
|
| 78173 | 465  | 
val worker_uuid = Generic.worker_uuid.make_primary_key  | 
466  | 
val build_uuid = Generic.build_uuid  | 
|
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
467  | 
      val start = SQL.Column.date("start")
 | 
| 77531 | 468  | 
      val stamp = SQL.Column.date("stamp")
 | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
469  | 
      val stop = SQL.Column.date("stop")
 | 
| 77531 | 470  | 
      val serial = SQL.Column.long("serial")
 | 
471  | 
||
| 78266 | 472  | 
val table =  | 
473  | 
make_table(List(worker_uuid, build_uuid, start, stamp, stop, serial), name = "workers")  | 
|
| 77531 | 474  | 
}  | 
475  | 
||
| 77655 | 476  | 
def read_serial(db: SQL.Database): Long =  | 
477  | 
db.execute_query_statementO[Long](  | 
|
| 78151 | 478  | 
Workers.table.select(List(Workers.serial.max)), _.long(Workers.serial)).getOrElse(0L)  | 
| 77655 | 479  | 
|
| 77586 | 480  | 
def read_workers(  | 
481  | 
db: SQL.Database,  | 
|
482  | 
build_uuid: String = "",  | 
|
483  | 
worker_uuid: String = ""  | 
|
| 
77657
 
a2a4adc268b8
removed redundant State.workers: directly maintained within the database, using with SQL update;
 
wenzelm 
parents: 
77656 
diff
changeset
 | 
484  | 
    ): List[Worker] = {
 | 
| 77586 | 485  | 
db.execute_query_statement(  | 
| 77662 | 486  | 
Workers.table.select(  | 
487  | 
sql = Generic.sql_where(build_uuid = build_uuid, worker_uuid = worker_uuid)),  | 
|
| 77586 | 488  | 
List.from[Worker],  | 
489  | 
          { res =>
 | 
|
490  | 
Worker(  | 
|
491  | 
worker_uuid = res.string(Workers.worker_uuid),  | 
|
492  | 
build_uuid = res.string(Workers.build_uuid),  | 
|
493  | 
start = res.date(Workers.start),  | 
|
494  | 
stamp = res.date(Workers.stamp),  | 
|
495  | 
stop = res.get_date(Workers.stop),  | 
|
496  | 
serial = res.long(Workers.serial))  | 
|
497  | 
})  | 
|
498  | 
}  | 
|
499  | 
||
| 77584 | 500  | 
def start_worker(  | 
501  | 
db: SQL.Database,  | 
|
502  | 
worker_uuid: String,  | 
|
503  | 
build_uuid: String,  | 
|
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
504  | 
serial: Long  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
505  | 
    ): Unit = {
 | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
506  | 
def err(msg: String): Nothing =  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
507  | 
        error("Cannot start worker " + worker_uuid + if_proper(msg, "\n" + msg))
 | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
508  | 
|
| 77552 | 509  | 
val build_stop =  | 
510  | 
db.execute_query_statementO(  | 
|
| 77636 | 511  | 
Base.table.select(List(Base.stop), sql = Base.build_uuid.where_equal(build_uuid)),  | 
| 77552 | 512  | 
res => res.get_date(Base.stop))  | 
513  | 
||
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
514  | 
      build_stop match {
 | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
515  | 
case Some(None) =>  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
516  | 
        case Some(Some(_)) => err("for already stopped build process " + build_uuid)
 | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
517  | 
        case None => err("for unknown build process " + build_uuid)
 | 
| 77531 | 518  | 
}  | 
519  | 
||
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
520  | 
db.execute_statement(Workers.table.insert(), body =  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
521  | 
        { stmt =>
 | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
522  | 
val now = db.now()  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
523  | 
stmt.string(1) = worker_uuid  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
524  | 
stmt.string(2) = build_uuid  | 
| 
78172
 
43ed2541b758
omit redundant data: already stored in progress database;
 
wenzelm 
parents: 
78170 
diff
changeset
 | 
525  | 
stmt.date(3) = now  | 
| 
 
43ed2541b758
omit redundant data: already stored in progress database;
 
wenzelm 
parents: 
78170 
diff
changeset
 | 
526  | 
stmt.date(4) = now  | 
| 
 
43ed2541b758
omit redundant data: already stored in progress database;
 
wenzelm 
parents: 
78170 
diff
changeset
 | 
527  | 
stmt.date(5) = None  | 
| 
 
43ed2541b758
omit redundant data: already stored in progress database;
 
wenzelm 
parents: 
78170 
diff
changeset
 | 
528  | 
stmt.long(6) = serial  | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
529  | 
})  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
530  | 
}  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
531  | 
|
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
532  | 
def stamp_worker(  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
533  | 
db: SQL.Database,  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
534  | 
worker_uuid: String,  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
535  | 
serial: Long,  | 
| 
78246
 
76dd9b9cf624
more robust "stop": further "stamp" ticks may happen afterwards;
 
wenzelm 
parents: 
78245 
diff
changeset
 | 
536  | 
stop_now: Boolean = false  | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
537  | 
    ): Unit = {
 | 
| 
78246
 
76dd9b9cf624
more robust "stop": further "stamp" ticks may happen afterwards;
 
wenzelm 
parents: 
78245 
diff
changeset
 | 
538  | 
val sql = Workers.worker_uuid.where_equal(worker_uuid)  | 
| 
 
76dd9b9cf624
more robust "stop": further "stamp" ticks may happen afterwards;
 
wenzelm 
parents: 
78245 
diff
changeset
 | 
539  | 
|
| 
 
76dd9b9cf624
more robust "stop": further "stamp" ticks may happen afterwards;
 
wenzelm 
parents: 
78245 
diff
changeset
 | 
540  | 
val stop =  | 
| 
 
76dd9b9cf624
more robust "stop": further "stamp" ticks may happen afterwards;
 
wenzelm 
parents: 
78245 
diff
changeset
 | 
541  | 
db.execute_query_statementO(  | 
| 
 
76dd9b9cf624
more robust "stop": further "stamp" ticks may happen afterwards;
 
wenzelm 
parents: 
78245 
diff
changeset
 | 
542  | 
Workers.table.select(List(Workers.stop), sql = sql), _.get_date(Workers.stop)).flatten  | 
| 
 
76dd9b9cf624
more robust "stop": further "stamp" ticks may happen afterwards;
 
wenzelm 
parents: 
78245 
diff
changeset
 | 
543  | 
|
| 78241 | 544  | 
db.execute_statement(  | 
| 
78246
 
76dd9b9cf624
more robust "stop": further "stamp" ticks may happen afterwards;
 
wenzelm 
parents: 
78245 
diff
changeset
 | 
545  | 
Workers.table.update(List(Workers.stamp, Workers.stop, Workers.serial), sql = sql),  | 
| 78241 | 546  | 
        body = { stmt =>
 | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
547  | 
val now = db.now()  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
548  | 
stmt.date(1) = now  | 
| 
78246
 
76dd9b9cf624
more robust "stop": further "stamp" ticks may happen afterwards;
 
wenzelm 
parents: 
78245 
diff
changeset
 | 
549  | 
stmt.date(2) = if (stop_now) Some(now) else stop  | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
550  | 
stmt.long(3) = serial  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
551  | 
})  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
552  | 
}  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
553  | 
|
| 77531 | 554  | 
|
555  | 
/* pending jobs */  | 
|
556  | 
||
557  | 
    object Pending {
 | 
|
558  | 
val name = Generic.name.make_primary_key  | 
|
559  | 
      val deps = SQL.Column.string("deps")
 | 
|
560  | 
      val info = SQL.Column.string("info")
 | 
|
| 
77661
 
45bd5c26cbcc
proper build_uuid for Build_Process.Task: thus old entries are removed via prepare_database/clean_build;
 
wenzelm 
parents: 
77660 
diff
changeset
 | 
561  | 
val build_uuid = Generic.build_uuid  | 
| 77531 | 562  | 
|
| 78266 | 563  | 
val table = make_table(List(name, deps, info, build_uuid), name = "pending")  | 
| 77531 | 564  | 
}  | 
565  | 
||
| 77585 | 566  | 
def read_pending(db: SQL.Database): List[Task] =  | 
| 77552 | 567  | 
db.execute_query_statement(  | 
568  | 
Pending.table.select(sql = SQL.order_by(List(Pending.name))),  | 
|
| 77585 | 569  | 
List.from[Task],  | 
| 77552 | 570  | 
        { res =>
 | 
571  | 
val name = res.string(Pending.name)  | 
|
572  | 
val deps = res.string(Pending.deps)  | 
|
573  | 
val info = res.string(Pending.info)  | 
|
| 
77661
 
45bd5c26cbcc
proper build_uuid for Build_Process.Task: thus old entries are removed via prepare_database/clean_build;
 
wenzelm 
parents: 
77660 
diff
changeset
 | 
574  | 
val build_uuid = res.string(Pending.build_uuid)  | 
| 
 
45bd5c26cbcc
proper build_uuid for Build_Process.Task: thus old entries are removed via prepare_database/clean_build;
 
wenzelm 
parents: 
77660 
diff
changeset
 | 
575  | 
Task(name, split_lines(deps), JSON.Object.parse(info), build_uuid)  | 
| 77552 | 576  | 
})  | 
| 77372 | 577  | 
|
| 78553 | 578  | 
def update_pending(  | 
579  | 
db: SQL.Database,  | 
|
580  | 
pending: State.Pending,  | 
|
581  | 
old_pending: State.Pending  | 
|
582  | 
    ): Boolean = {
 | 
|
| 77372 | 583  | 
val (delete, insert) = Library.symmetric_difference(old_pending, pending)  | 
584  | 
||
585  | 
      if (delete.nonEmpty) {
 | 
|
| 77540 | 586  | 
db.execute_statement(  | 
| 77662 | 587  | 
Pending.table.delete(sql = Generic.sql_where(names = delete.map(_.name))))  | 
| 77372 | 588  | 
}  | 
589  | 
||
| 
78552
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
590  | 
      if (insert.nonEmpty) {
 | 
| 
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
591  | 
db.execute_batch_statement(Pending.table.insert(), batch =  | 
| 
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
592  | 
          for (task <- insert) yield { (stmt: SQL.Statement) =>
 | 
| 
77661
 
45bd5c26cbcc
proper build_uuid for Build_Process.Task: thus old entries are removed via prepare_database/clean_build;
 
wenzelm 
parents: 
77660 
diff
changeset
 | 
593  | 
stmt.string(1) = task.name  | 
| 
 
45bd5c26cbcc
proper build_uuid for Build_Process.Task: thus old entries are removed via prepare_database/clean_build;
 
wenzelm 
parents: 
77660 
diff
changeset
 | 
594  | 
stmt.string(2) = cat_lines(task.deps)  | 
| 
 
45bd5c26cbcc
proper build_uuid for Build_Process.Task: thus old entries are removed via prepare_database/clean_build;
 
wenzelm 
parents: 
77660 
diff
changeset
 | 
595  | 
stmt.string(3) = JSON.Format(task.info)  | 
| 
 
45bd5c26cbcc
proper build_uuid for Build_Process.Task: thus old entries are removed via prepare_database/clean_build;
 
wenzelm 
parents: 
77660 
diff
changeset
 | 
596  | 
stmt.string(4) = task.build_uuid  | 
| 77541 | 597  | 
})  | 
| 77372 | 598  | 
}  | 
599  | 
||
600  | 
delete.nonEmpty || insert.nonEmpty  | 
|
601  | 
}  | 
|
602  | 
||
| 77531 | 603  | 
|
604  | 
/* running jobs */  | 
|
605  | 
||
606  | 
    object Running {
 | 
|
607  | 
val name = Generic.name.make_primary_key  | 
|
| 77587 | 608  | 
val worker_uuid = Generic.worker_uuid  | 
| 77634 | 609  | 
val build_uuid = Generic.build_uuid  | 
| 77531 | 610  | 
      val hostname = SQL.Column.string("hostname")
 | 
611  | 
      val numa_node = SQL.Column.int("numa_node")
 | 
|
612  | 
||
| 78266 | 613  | 
val table =  | 
614  | 
make_table(List(name, worker_uuid, build_uuid, hostname, numa_node), name = "running")  | 
|
| 77531 | 615  | 
}  | 
616  | 
||
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
617  | 
def read_running(db: SQL.Database): State.Running =  | 
| 77552 | 618  | 
db.execute_query_statement(  | 
619  | 
Running.table.select(sql = SQL.order_by(List(Running.name))),  | 
|
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
620  | 
Map.from[String, Job],  | 
| 77552 | 621  | 
        { res =>
 | 
622  | 
val name = res.string(Running.name)  | 
|
| 77587 | 623  | 
val worker_uuid = res.string(Running.worker_uuid)  | 
| 77634 | 624  | 
val build_uuid = res.string(Running.build_uuid)  | 
| 77552 | 625  | 
val hostname = res.string(Running.hostname)  | 
626  | 
val numa_node = res.get_int(Running.numa_node)  | 
|
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
627  | 
name -> Job(name, worker_uuid, build_uuid, Host.Node_Info(hostname, numa_node), None)  | 
| 77552 | 628  | 
}  | 
629  | 
)  | 
|
| 77372 | 630  | 
|
| 78553 | 631  | 
def update_running(  | 
632  | 
db: SQL.Database,  | 
|
633  | 
running: State.Running,  | 
|
634  | 
old_running: State.Running  | 
|
635  | 
    ): Boolean = {
 | 
|
636  | 
val running0 = old_running.valuesIterator.toList  | 
|
| 
78573
 
980f3cfcbc2c
more accurate treatment of state vs. serial vs. db;
 
wenzelm 
parents: 
78571 
diff
changeset
 | 
637  | 
val running1 = running.valuesIterator.toList  | 
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
638  | 
val (delete, insert) = Library.symmetric_difference(running0, running1)  | 
| 77372 | 639  | 
|
640  | 
      if (delete.nonEmpty) {
 | 
|
| 77540 | 641  | 
db.execute_statement(  | 
| 77662 | 642  | 
Running.table.delete(sql = Generic.sql_where(names = delete.map(_.name))))  | 
| 77372 | 643  | 
}  | 
644  | 
||
| 
78552
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
645  | 
      if (insert.nonEmpty) {
 | 
| 
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
646  | 
db.execute_batch_statement(Running.table.insert(), batch =  | 
| 
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
647  | 
          for (job <- insert) yield { (stmt: SQL.Statement) =>
 | 
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
648  | 
stmt.string(1) = job.name  | 
| 77587 | 649  | 
stmt.string(2) = job.worker_uuid  | 
| 77634 | 650  | 
stmt.string(3) = job.build_uuid  | 
651  | 
stmt.string(4) = job.node_info.hostname  | 
|
652  | 
stmt.int(5) = job.node_info.numa_node  | 
|
| 77541 | 653  | 
})  | 
| 77372 | 654  | 
}  | 
655  | 
||
656  | 
delete.nonEmpty || insert.nonEmpty  | 
|
657  | 
}  | 
|
658  | 
||
| 77531 | 659  | 
|
660  | 
/* job results */  | 
|
661  | 
||
662  | 
    object Results {
 | 
|
663  | 
val name = Generic.name.make_primary_key  | 
|
| 77651 | 664  | 
val worker_uuid = Generic.worker_uuid  | 
665  | 
val build_uuid = Generic.build_uuid  | 
|
| 77531 | 666  | 
      val hostname = SQL.Column.string("hostname")
 | 
667  | 
      val numa_node = SQL.Column.string("numa_node")
 | 
|
668  | 
      val rc = SQL.Column.int("rc")
 | 
|
669  | 
      val out = SQL.Column.string("out")
 | 
|
670  | 
      val err = SQL.Column.string("err")
 | 
|
671  | 
      val timing_elapsed = SQL.Column.long("timing_elapsed")
 | 
|
672  | 
      val timing_cpu = SQL.Column.long("timing_cpu")
 | 
|
673  | 
      val timing_gc = SQL.Column.long("timing_gc")
 | 
|
| 77651 | 674  | 
      val output_shasum = SQL.Column.string("output_shasum")
 | 
675  | 
      val current = SQL.Column.bool("current")
 | 
|
| 77531 | 676  | 
|
677  | 
val table =  | 
|
| 78266 | 678  | 
make_table(  | 
| 77651 | 679  | 
List(name, worker_uuid, build_uuid, hostname, numa_node,  | 
| 78266 | 680  | 
rc, out, err, timing_elapsed, timing_cpu, timing_gc, output_shasum, current),  | 
681  | 
name = "results")  | 
|
| 77531 | 682  | 
}  | 
683  | 
||
| 77496 | 684  | 
def read_results_domain(db: SQL.Database): Set[String] =  | 
| 77552 | 685  | 
db.execute_query_statement(  | 
686  | 
Results.table.select(List(Results.name)),  | 
|
687  | 
Set.from[String], res => res.string(Results.name))  | 
|
| 77496 | 688  | 
|
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
689  | 
def read_results(db: SQL.Database, names: Iterable[String] = Nil): State.Results =  | 
| 77552 | 690  | 
db.execute_query_statement(  | 
691  | 
Results.table.select(sql = if_proper(names, Results.name.where_member(names))),  | 
|
| 77651 | 692  | 
Map.from[String, Result],  | 
| 77552 | 693  | 
        { res =>
 | 
694  | 
val name = res.string(Results.name)  | 
|
| 77651 | 695  | 
val worker_uuid = res.string(Results.worker_uuid)  | 
696  | 
val build_uuid = res.string(Results.build_uuid)  | 
|
| 77552 | 697  | 
val hostname = res.string(Results.hostname)  | 
698  | 
val numa_node = res.get_int(Results.numa_node)  | 
|
| 77651 | 699  | 
val node_info = Host.Node_Info(hostname, numa_node)  | 
700  | 
||
| 77552 | 701  | 
val rc = res.int(Results.rc)  | 
702  | 
val out = res.string(Results.out)  | 
|
703  | 
val err = res.string(Results.err)  | 
|
704  | 
val timing =  | 
|
705  | 
res.timing(  | 
|
706  | 
Results.timing_elapsed,  | 
|
707  | 
Results.timing_cpu,  | 
|
708  | 
Results.timing_gc)  | 
|
709  | 
val process_result =  | 
|
710  | 
Process_Result(rc,  | 
|
711  | 
out_lines = split_lines(out),  | 
|
712  | 
err_lines = split_lines(err),  | 
|
713  | 
timing = timing)  | 
|
| 77651 | 714  | 
|
715  | 
val output_shasum = SHA1.fake_shasum(res.string(Results.output_shasum))  | 
|
716  | 
val current = res.bool(Results.current)  | 
|
717  | 
||
718  | 
name ->  | 
|
719  | 
Result(name, worker_uuid, build_uuid, node_info, process_result, output_shasum, current)  | 
|
| 77496 | 720  | 
}  | 
| 77552 | 721  | 
)  | 
| 77372 | 722  | 
|
| 78553 | 723  | 
def update_results(  | 
724  | 
db: SQL.Database,  | 
|
725  | 
results: State.Results,  | 
|
726  | 
old_results: State.Results  | 
|
727  | 
    ): Boolean = {
 | 
|
| 78267 | 728  | 
val insert =  | 
| 78553 | 729  | 
results.valuesIterator.filterNot(res => old_results.isDefinedAt(res.name)).toList  | 
| 77372 | 730  | 
|
| 
78552
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
731  | 
      if (insert.nonEmpty) {
 | 
| 
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
732  | 
db.execute_batch_statement(Results.table.insert(), batch =  | 
| 
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
733  | 
          for (result <- insert) yield { (stmt: SQL.Statement) =>
 | 
| 
 
384adc74e27d
performance tuning: avoid multiple db roundtrips;
 
wenzelm 
parents: 
78546 
diff
changeset
 | 
734  | 
val process_result = result.process_result  | 
| 77651 | 735  | 
stmt.string(1) = result.name  | 
736  | 
stmt.string(2) = result.worker_uuid  | 
|
737  | 
stmt.string(3) = result.build_uuid  | 
|
738  | 
stmt.string(4) = result.node_info.hostname  | 
|
739  | 
stmt.int(5) = result.node_info.numa_node  | 
|
740  | 
stmt.int(6) = process_result.rc  | 
|
741  | 
stmt.string(7) = cat_lines(process_result.out_lines)  | 
|
742  | 
stmt.string(8) = cat_lines(process_result.err_lines)  | 
|
743  | 
stmt.long(9) = process_result.timing.elapsed.ms  | 
|
744  | 
stmt.long(10) = process_result.timing.cpu.ms  | 
|
745  | 
stmt.long(11) = process_result.timing.gc.ms  | 
|
746  | 
stmt.string(12) = result.output_shasum.toString  | 
|
747  | 
stmt.bool(13) = result.current  | 
|
| 77541 | 748  | 
})  | 
| 77372 | 749  | 
}  | 
750  | 
||
751  | 
insert.nonEmpty  | 
|
752  | 
}  | 
|
753  | 
||
| 77531 | 754  | 
|
755  | 
/* collective operations */  | 
|
756  | 
||
| 
78187
 
2df0f3604a67
clarified signature: more explicit class SQL.Data;
 
wenzelm 
parents: 
78185 
diff
changeset
 | 
757  | 
override val tables =  | 
| 77596 | 758  | 
SQL.Tables(  | 
| 77534 | 759  | 
Base.table,  | 
760  | 
Workers.table,  | 
|
761  | 
Sessions.table,  | 
|
762  | 
Pending.table,  | 
|
763  | 
Running.table,  | 
|
| 
78174
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
764  | 
Results.table)  | 
| 77534 | 765  | 
|
| 77658 | 766  | 
val build_uuid_tables =  | 
| 
78187
 
2df0f3604a67
clarified signature: more explicit class SQL.Data;
 
wenzelm 
parents: 
78185 
diff
changeset
 | 
767  | 
tables.filter(table =>  | 
| 77658 | 768  | 
table.columns.exists(column => column.name == Generic.build_uuid.name))  | 
769  | 
||
| 78546 | 770  | 
    def pull_database(db: SQL.Database, worker_uuid: String, state: State): State = {
 | 
| 77655 | 771  | 
val serial_db = read_serial(db)  | 
772  | 
if (serial_db == state.serial) state  | 
|
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
773  | 
      else {
 | 
| 77655 | 774  | 
val serial = serial_db max state.serial  | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
775  | 
stamp_worker(db, worker_uuid, serial)  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
776  | 
|
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
777  | 
val sessions = state.sessions.pull(read_sessions_domain(db), read_sessions(db, _))  | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
778  | 
val pending = read_pending(db)  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
779  | 
val running = pull0(read_running(db), state.running)  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
780  | 
val results = pull1(read_results_domain(db), read_results(db, _), state.results)  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
781  | 
|
| 
78174
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
782  | 
state.copy(serial = serial, sessions = sessions, pending = pending,  | 
| 
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
783  | 
running = running, results = results)  | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
784  | 
}  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
785  | 
}  | 
| 
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
786  | 
|
| 78553 | 787  | 
def update_database(  | 
788  | 
db: SQL.Database,  | 
|
789  | 
worker_uuid: String,  | 
|
790  | 
state: State,  | 
|
791  | 
old_state: State  | 
|
792  | 
    ): State = {
 | 
|
| 
77416
 
d88c12f22ab0
clarified scope of "serial" and "numa_index" within database;
 
wenzelm 
parents: 
77415 
diff
changeset
 | 
793  | 
val changed =  | 
| 
 
d88c12f22ab0
clarified scope of "serial" and "numa_index" within database;
 
wenzelm 
parents: 
77415 
diff
changeset
 | 
794  | 
List(  | 
| 78553 | 795  | 
update_sessions(db, state.sessions, old_state.sessions),  | 
796  | 
update_pending(db, state.pending, old_state.pending),  | 
|
797  | 
update_running(db, state.running, old_state.running),  | 
|
798  | 
update_results(db, state.results, old_state.results))  | 
|
| 77372 | 799  | 
|
| 78574 | 800  | 
val state1 = if (changed.exists(identity)) state.inc_serial else state  | 
801  | 
if (state1.serial != state.serial) stamp_worker(db, worker_uuid, state1.serial)  | 
|
| 77372 | 802  | 
|
| 78574 | 803  | 
state1  | 
| 77372 | 804  | 
}  | 
805  | 
}  | 
|
| 
78218
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
806  | 
|
| 
 
a625bfb0e549
clarified signature: more operations and options;
 
wenzelm 
parents: 
78217 
diff
changeset
 | 
807  | 
def read_builds(db: SQL.Database): List[Build] =  | 
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
808  | 
    private_data.transaction_lock(db, create = true, label = "Build_Process.read_builds") {
 | 
| 
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
809  | 
private_data.read_builds(db)  | 
| 78356 | 810  | 
}  | 
| 77396 | 811  | 
}  | 
| 77372 | 812  | 
|
813  | 
||
| 77436 | 814  | 
|
815  | 
/** main process **/  | 
|
| 
77259
 
61fc2afe4c8b
clarified signature: prefer stateful object-oriented style, to make it fit better into physical world;
 
wenzelm 
parents: 
77258 
diff
changeset
 | 
816  | 
|
| 77505 | 817  | 
class Build_Process(  | 
| 78421 | 818  | 
protected final val build_context: Build.Context,  | 
| 78372 | 819  | 
protected final val build_progress: Progress,  | 
820  | 
protected final val server: SSH.Server  | 
|
| 77505 | 821  | 
)  | 
| 77436 | 822  | 
extends AutoCloseable {
 | 
823  | 
/* context */  | 
|
824  | 
||
| 78178 | 825  | 
protected final val store: Store = build_context.store  | 
| 77530 | 826  | 
protected final val build_options: Options = store.options  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
827  | 
protected final val build_deps: isabelle.Sessions.Deps = build_context.build_deps  | 
| 77653 | 828  | 
protected final val hostname: String = build_context.hostname  | 
| 77530 | 829  | 
protected final val build_uuid: String = build_context.build_uuid  | 
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
830  | 
|
| 
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
831  | 
|
| 78413 | 832  | 
/* global resources with common close() operation */  | 
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
833  | 
|
| 78214 | 834  | 
private val _database_server: Option[SQL.Database] =  | 
| 78372 | 835  | 
    try { store.maybe_open_database_server(server = server) }
 | 
| 78214 | 836  | 
    catch { case exn: Throwable => close(); throw exn }
 | 
837  | 
||
| 78203 | 838  | 
private val _build_database: Option[SQL.Database] =  | 
| 78234 | 839  | 
    try {
 | 
| 78372 | 840  | 
      for (db <- store.maybe_open_build_database(server = server)) yield {
 | 
| 
78389
 
41e8ae87184d
clarified signature: eliminate SQL.Tables.empty to avoid confusion (see also 0bd366fad888);
 
wenzelm 
parents: 
78385 
diff
changeset
 | 
841  | 
val store_tables = db.is_postgresql  | 
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
842  | 
Build_Process.private_data.transaction_lock(db,  | 
| 78356 | 843  | 
create = true,  | 
844  | 
label = "Build_Process.build_database"  | 
|
845  | 
        ) {
 | 
|
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
846  | 
Build_Process.private_data.clean_build(db)  | 
| 
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
847  | 
if (store_tables) Store.private_data.tables.lock(db, create = true)  | 
| 78234 | 848  | 
}  | 
| 
78389
 
41e8ae87184d
clarified signature: eliminate SQL.Tables.empty to avoid confusion (see also 0bd366fad888);
 
wenzelm 
parents: 
78385 
diff
changeset
 | 
849  | 
        if (build_context.master) {
 | 
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
850  | 
db.vacuum(Build_Process.private_data.tables.list)  | 
| 
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
851  | 
if (store_tables) db.vacuum(Store.private_data.tables.list)  | 
| 
78389
 
41e8ae87184d
clarified signature: eliminate SQL.Tables.empty to avoid confusion (see also 0bd366fad888);
 
wenzelm 
parents: 
78385 
diff
changeset
 | 
852  | 
}  | 
| 78234 | 853  | 
db  | 
854  | 
}  | 
|
855  | 
}  | 
|
| 78214 | 856  | 
    catch { case exn: Throwable => close(); throw exn }
 | 
| 
77259
 
61fc2afe4c8b
clarified signature: prefer stateful object-oriented style, to make it fit better into physical world;
 
wenzelm 
parents: 
77258 
diff
changeset
 | 
857  | 
|
| 78409 | 858  | 
  protected val build_delay: Time = {
 | 
859  | 
val option =  | 
|
860  | 
      _build_database match {
 | 
|
861  | 
case Some(db) if db.is_postgresql => "build_cluster_delay"  | 
|
862  | 
case _ => "build_delay"  | 
|
863  | 
}  | 
|
864  | 
build_options.seconds(option)  | 
|
865  | 
}  | 
|
| 
78406
 
2ece6509ad6f
clarified options: accommodate potentially slow database connection;
 
wenzelm 
parents: 
78401 
diff
changeset
 | 
866  | 
|
| 
78174
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
867  | 
private val _host_database: Option[SQL.Database] =  | 
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
868  | 
    try { store.maybe_open_build_database(path = Host.private_data.database, server = server) }
 | 
| 78214 | 869  | 
    catch { case exn: Throwable => close(); throw exn }
 | 
| 
78213
 
fd0430a7b7a4
avoid repeated open_database_server: synchronized transaction_lock;
 
wenzelm 
parents: 
78205 
diff
changeset
 | 
870  | 
|
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
871  | 
  protected val (progress, worker_uuid) = synchronized {
 | 
| 78569 | 872  | 
if (_build_database.isEmpty) (build_progress, UUID.random().toString)  | 
873  | 
    else {
 | 
|
874  | 
      try {
 | 
|
875  | 
val db = store.open_build_database(Progress.private_data.database, server = server)  | 
|
876  | 
val progress =  | 
|
877  | 
new Database_Progress(db, build_progress,  | 
|
878  | 
input_messages = build_context.master,  | 
|
879  | 
output_stopped = build_context.master,  | 
|
880  | 
hostname = hostname,  | 
|
881  | 
context_uuid = build_uuid,  | 
|
882  | 
kind = "build_process",  | 
|
883  | 
timeout = Some(build_delay))  | 
|
884  | 
(progress, progress.agent_uuid)  | 
|
885  | 
}  | 
|
886  | 
      catch { case exn: Throwable => close(); throw exn }
 | 
|
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
887  | 
}  | 
| 
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
888  | 
}  | 
| 77638 | 889  | 
|
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
890  | 
protected val log: Logger = Logger.make_system_log(progress, build_options)  | 
| 
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
891  | 
|
| 
78434
 
b4ec7ea073da
clarified signature: delegate policies to Build_Cluster implementation, potentially provided by Build.Engine via Build_Process.open_build_cluster;
 
wenzelm 
parents: 
78430 
diff
changeset
 | 
892  | 
  protected def open_build_cluster(): Build_Cluster = {
 | 
| 
 
b4ec7ea073da
clarified signature: delegate policies to Build_Cluster implementation, potentially provided by Build.Engine via Build_Process.open_build_cluster;
 
wenzelm 
parents: 
78430 
diff
changeset
 | 
893  | 
val build_cluster = Build_Cluster.make(build_context, progress = build_progress)  | 
| 
 
b4ec7ea073da
clarified signature: delegate policies to Build_Cluster implementation, potentially provided by Build.Engine via Build_Process.open_build_cluster;
 
wenzelm 
parents: 
78430 
diff
changeset
 | 
894  | 
build_cluster.open()  | 
| 
 
b4ec7ea073da
clarified signature: delegate policies to Build_Cluster implementation, potentially provided by Build.Engine via Build_Process.open_build_cluster;
 
wenzelm 
parents: 
78430 
diff
changeset
 | 
895  | 
build_cluster  | 
| 
78430
 
0461fc9d43e8
more build_cluster management: open SSH connections in parallel, but synchronously;
 
wenzelm 
parents: 
78424 
diff
changeset
 | 
896  | 
}  | 
| 
 
0461fc9d43e8
more build_cluster management: open SSH connections in parallel, but synchronously;
 
wenzelm 
parents: 
78424 
diff
changeset
 | 
897  | 
|
| 78413 | 898  | 
private val _build_cluster =  | 
899  | 
    try {
 | 
|
| 
78434
 
b4ec7ea073da
clarified signature: delegate policies to Build_Cluster implementation, potentially provided by Build.Engine via Build_Process.open_build_cluster;
 
wenzelm 
parents: 
78430 
diff
changeset
 | 
900  | 
if (build_context.master && _build_database.isDefined) open_build_cluster()  | 
| 
 
b4ec7ea073da
clarified signature: delegate policies to Build_Cluster implementation, potentially provided by Build.Engine via Build_Process.open_build_cluster;
 
wenzelm 
parents: 
78430 
diff
changeset
 | 
901  | 
else Build_Cluster.none  | 
| 78413 | 902  | 
}  | 
903  | 
    catch { case exn: Throwable => close(); throw exn }
 | 
|
904  | 
||
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
905  | 
  def close(): Unit = synchronized {
 | 
| 78214 | 906  | 
Option(_database_server).flatten.foreach(_.close())  | 
907  | 
Option(_build_database).flatten.foreach(_.close())  | 
|
908  | 
Option(_host_database).flatten.foreach(_.close())  | 
|
| 
78434
 
b4ec7ea073da
clarified signature: delegate policies to Build_Cluster implementation, potentially provided by Build.Engine via Build_Process.open_build_cluster;
 
wenzelm 
parents: 
78430 
diff
changeset
 | 
909  | 
Option(_build_cluster).foreach(_.close())  | 
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
910  | 
    progress match {
 | 
| 78563 | 911  | 
case db_progress: Database_Progress => db_progress.exit(close = true)  | 
| 78159 | 912  | 
case _ =>  | 
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
913  | 
}  | 
| 
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
914  | 
}  | 
| 77436 | 915  | 
|
| 78413 | 916  | 
|
| 
77437
 
dcbf96acae27
clarified signature: do not expose global state to object-oriented variants;
 
wenzelm 
parents: 
77436 
diff
changeset
 | 
917  | 
/* global state: internal var vs. external database */  | 
| 77436 | 918  | 
|
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
919  | 
private var _state: Build_Process.State = Build_Process.State()  | 
| 
77437
 
dcbf96acae27
clarified signature: do not expose global state to object-oriented variants;
 
wenzelm 
parents: 
77436 
diff
changeset
 | 
920  | 
|
| 78356 | 921  | 
protected def synchronized_database[A](label: String)(body: => A): A =  | 
922  | 
    synchronized {
 | 
|
923  | 
      _build_database match {
 | 
|
924  | 
case None => body  | 
|
925  | 
case Some(db) =>  | 
|
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
926  | 
          Build_Process.private_data.transaction_lock(db, label = label) {
 | 
| 78553 | 927  | 
val old_state = Build_Process.private_data.pull_database(db, worker_uuid, _state)  | 
928  | 
_state = old_state  | 
|
| 78356 | 929  | 
val res = body  | 
| 78553 | 930  | 
_state = Build_Process.private_data.update_database(db, worker_uuid, _state, old_state)  | 
| 78356 | 931  | 
res  | 
932  | 
}  | 
|
933  | 
}  | 
|
| 
77522
 
a1d30297cd61
more complete coverage of non-final Progress methods, notably for Server.Connection_Progress;
 
wenzelm 
parents: 
77521 
diff
changeset
 | 
934  | 
}  | 
| 
 
a1d30297cd61
more complete coverage of non-final Progress methods, notably for Server.Connection_Progress;
 
wenzelm 
parents: 
77521 
diff
changeset
 | 
935  | 
|
| 77505 | 936  | 
|
| 
77437
 
dcbf96acae27
clarified signature: do not expose global state to object-oriented variants;
 
wenzelm 
parents: 
77436 
diff
changeset
 | 
937  | 
/* policy operations */  | 
| 77333 | 938  | 
|
| 
77415
 
6b928419f109
clarified signature: allow more general init, e.g. from existing database;
 
wenzelm 
parents: 
77414 
diff
changeset
 | 
939  | 
  protected def init_state(state: Build_Process.State): Build_Process.State = {
 | 
| 78374 | 940  | 
val sessions1 = state.sessions.init(build_context, _database_server, progress = build_progress)  | 
| 77496 | 941  | 
|
| 
77415
 
6b928419f109
clarified signature: allow more general init, e.g. from existing database;
 
wenzelm 
parents: 
77414 
diff
changeset
 | 
942  | 
val old_pending = state.pending.iterator.map(_.name).toSet  | 
| 
 
6b928419f109
clarified signature: allow more general init, e.g. from existing database;
 
wenzelm 
parents: 
77414 
diff
changeset
 | 
943  | 
val new_pending =  | 
| 
 
6b928419f109
clarified signature: allow more general init, e.g. from existing database;
 
wenzelm 
parents: 
77414 
diff
changeset
 | 
944  | 
List.from(  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
945  | 
for (session <- sessions1.iterator if !old_pending(session.name))  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
946  | 
yield Build_Process.Task(session.name, session.deps, JSON.Object.empty, build_uuid))  | 
| 77496 | 947  | 
val pending1 = new_pending ::: state.pending  | 
948  | 
||
| 78571 | 949  | 
state.copy(sessions = sessions1, pending = pending1)  | 
| 
77415
 
6b928419f109
clarified signature: allow more general init, e.g. from existing database;
 
wenzelm 
parents: 
77414 
diff
changeset
 | 
950  | 
}  | 
| 
77259
 
61fc2afe4c8b
clarified signature: prefer stateful object-oriented style, to make it fit better into physical world;
 
wenzelm 
parents: 
77258 
diff
changeset
 | 
951  | 
|
| 
78394
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
952  | 
  protected def next_jobs(state: Build_Process.State): List[String] = {
 | 
| 
78529
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
953  | 
    val limit = {
 | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
954  | 
      if (progress.stopped) { if (build_context.master) Int.MaxValue else 0 }
 | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
955  | 
else build_context.max_jobs - state.build_running.length  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
956  | 
}  | 
| 
78394
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
957  | 
    if (limit > 0) {
 | 
| 
77437
 
dcbf96acae27
clarified signature: do not expose global state to object-oriented variants;
 
wenzelm 
parents: 
77436 
diff
changeset
 | 
958  | 
state.pending.filter(entry => entry.is_ready && !state.is_running(entry.name))  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
959  | 
.sortBy(_.name)(state.sessions.ordering)  | 
| 
78394
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
960  | 
.take(limit).map(_.name)  | 
| 
77296
 
eeaa2872320b
clarified signature: more explicit synchronized operations;
 
wenzelm 
parents: 
77295 
diff
changeset
 | 
961  | 
}  | 
| 
78394
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
962  | 
else Nil  | 
| 
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
963  | 
}  | 
| 
77259
 
61fc2afe4c8b
clarified signature: prefer stateful object-oriented style, to make it fit better into physical world;
 
wenzelm 
parents: 
77258 
diff
changeset
 | 
964  | 
|
| 
78500
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
965  | 
protected def start_session(  | 
| 
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
966  | 
state: Build_Process.State,  | 
| 
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
967  | 
session_name: String,  | 
| 
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
968  | 
ancestor_results: List[Build_Process.Result]  | 
| 
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
969  | 
  ): Build_Process.State = {
 | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
970  | 
val sources_shasum = state.sessions(session_name).sources_shasum  | 
| 
77467
 
e27bc7957297
more robust: proper synchronization of transition from next_job to start_session;
 
wenzelm 
parents: 
77466 
diff
changeset
 | 
971  | 
|
| 
77460
 
ccca589d7027
tuned signature: support general Build_Job instances;
 
wenzelm 
parents: 
77459 
diff
changeset
 | 
972  | 
val input_shasum =  | 
| 77650 | 973  | 
if (ancestor_results.isEmpty) ML_Process.bootstrap_shasum()  | 
| 
77460
 
ccca589d7027
tuned signature: support general Build_Job instances;
 
wenzelm 
parents: 
77459 
diff
changeset
 | 
974  | 
else SHA1.flat_shasum(ancestor_results.map(_.output_shasum))  | 
| 77257 | 975  | 
|
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
976  | 
val store_heap =  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
977  | 
build_context.build_heap || Sessions.is_pure(session_name) ||  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
978  | 
state.sessions.iterator.exists(_.ancestors.contains(session_name))  | 
| 77469 | 979  | 
|
980  | 
val (current, output_shasum) =  | 
|
| 78374 | 981  | 
store.check_output(_database_server, session_name,  | 
| 
77675
 
9e5f8f6e58a0
more thorough treatment of build prefs, guarded by system option "build_through": avoid accidental rebuild of HOL etc.;
 
wenzelm 
parents: 
77664 
diff
changeset
 | 
982  | 
session_options = build_context.sessions_structure(session_name).options,  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
983  | 
sources_shasum = sources_shasum,  | 
| 77469 | 984  | 
input_shasum = input_shasum,  | 
985  | 
fresh_build = build_context.fresh_build,  | 
|
986  | 
store_heap = store_heap)  | 
|
987  | 
||
| 78195 | 988  | 
val finished = current && ancestor_results.forall(_.current)  | 
989  | 
val skipped = build_context.no_build  | 
|
990  | 
val cancelled = progress.stopped || !ancestor_results.forall(_.ok)  | 
|
| 77257 | 991  | 
|
| 
78196
 
140a6f2e3728
restore heaps from database, which takes precedence over file-system;
 
wenzelm 
parents: 
78195 
diff
changeset
 | 
992  | 
    if (!skipped && !cancelled) {
 | 
| 
78510
 
8f45302a9ff0
more thorough ML_Heap.restore: include ancestors;                                                         prefer simultaneous ML_Heap.get_entries: just one database access for heap hierarchy;
 
wenzelm 
parents: 
78507 
diff
changeset
 | 
993  | 
val heaps = (session_name :: ancestor_results.map(_.name)).map(store.output_heap)  | 
| 
 
8f45302a9ff0
more thorough ML_Heap.restore: include ancestors;                                                         prefer simultaneous ML_Heap.get_entries: just one database access for heap hierarchy;
 
wenzelm 
parents: 
78507 
diff
changeset
 | 
994  | 
ML_Heap.restore(_database_server, heaps, cache = store.cache.compress)  | 
| 
78196
 
140a6f2e3728
restore heaps from database, which takes precedence over file-system;
 
wenzelm 
parents: 
78195 
diff
changeset
 | 
995  | 
}  | 
| 
 
140a6f2e3728
restore heaps from database, which takes precedence over file-system;
 
wenzelm 
parents: 
78195 
diff
changeset
 | 
996  | 
|
| 77651 | 997  | 
val result_name = (session_name, worker_uuid, build_uuid)  | 
998  | 
||
| 78195 | 999  | 
    if (finished) {
 | 
| 
77467
 
e27bc7957297
more robust: proper synchronization of transition from next_job to start_session;
 
wenzelm 
parents: 
77466 
diff
changeset
 | 
1000  | 
state  | 
| 
 
e27bc7957297
more robust: proper synchronization of transition from next_job to start_session;
 
wenzelm 
parents: 
77466 
diff
changeset
 | 
1001  | 
.remove_pending(session_name)  | 
| 77651 | 1002  | 
.make_result(result_name, Process_Result.ok, output_shasum, current = true)  | 
| 77260 | 1003  | 
}  | 
| 78195 | 1004  | 
    else if (skipped) {
 | 
| 
77521
 
5642de4d225d
clarified signature: manage "verbose" flag via "progress";
 
wenzelm 
parents: 
77514 
diff
changeset
 | 
1005  | 
      progress.echo("Skipping " + session_name + " ...", verbose = true)
 | 
| 
77467
 
e27bc7957297
more robust: proper synchronization of transition from next_job to start_session;
 
wenzelm 
parents: 
77466 
diff
changeset
 | 
1006  | 
state.  | 
| 
 
e27bc7957297
more robust: proper synchronization of transition from next_job to start_session;
 
wenzelm 
parents: 
77466 
diff
changeset
 | 
1007  | 
remove_pending(session_name).  | 
| 77651 | 1008  | 
make_result(result_name, Process_Result.error, output_shasum)  | 
| 77260 | 1009  | 
}  | 
| 78195 | 1010  | 
    else if (cancelled) {
 | 
| 
78529
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1011  | 
      if (build_context.master) {
 | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1012  | 
progress.echo(session_name + " CANCELLED")  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1013  | 
state  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1014  | 
.remove_pending(session_name)  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1015  | 
.make_result(result_name, Process_Result.undefined, output_shasum)  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1016  | 
}  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1017  | 
else state  | 
| 77452 | 1018  | 
}  | 
1019  | 
    else {
 | 
|
| 
78174
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
1020  | 
def used_nodes: Set[Int] =  | 
| 
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
1021  | 
Set.from(for (job <- state.running.valuesIterator; i <- job.node_info.numa_node) yield i)  | 
| 
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
1022  | 
val numa_node =  | 
| 
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
1023  | 
        for {
 | 
| 
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
1024  | 
db <- _host_database  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
1025  | 
n <- Host.next_numa_node(db, hostname, state.numa_nodes, used_nodes)  | 
| 
78174
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
1026  | 
} yield n  | 
| 77653 | 1027  | 
val node_info = Host.Node_Info(hostname, numa_node)  | 
| 77551 | 1028  | 
|
| 78575 | 1029  | 
val print_node_info =  | 
1030  | 
node_info.numa_node.isDefined ||  | 
|
1031  | 
_build_database.isDefined && _build_database.get.is_postgresql  | 
|
1032  | 
||
| 77551 | 1033  | 
progress.echo(  | 
1034  | 
(if (store_heap) "Building " else "Running ") + session_name +  | 
|
| 78575 | 1035  | 
(if (print_node_info) " (on " + node_info + ")" else "") + " ...")  | 
| 77260 | 1036  | 
|
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
1037  | 
val session = state.sessions(session_name)  | 
| 
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
1038  | 
|
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
1039  | 
val build =  | 
| 78372 | 1040  | 
Build_Job.start_session(build_context, session, progress, log, server,  | 
| 
78237
 
c2c59de57df9
clarified static Build_Process.Context vs. dynamic Build_Process.State;
 
wenzelm 
parents: 
78234 
diff
changeset
 | 
1041  | 
build_deps.background(session_name), sources_shasum, input_shasum, node_info, store_heap)  | 
| 
77630
 
86ef80d13544
clarified signature: avoid confusion due to object-orientation;
 
wenzelm 
parents: 
77629 
diff
changeset
 | 
1042  | 
|
| 77634 | 1043  | 
val job = Build_Process.Job(session_name, worker_uuid, build_uuid, node_info, Some(build))  | 
1044  | 
||
| 
78174
 
cc0bd66eb498
separate host.db for independent db.transaction_lock;
 
wenzelm 
parents: 
78173 
diff
changeset
 | 
1045  | 
state.add_running(job)  | 
| 77260 | 1046  | 
}  | 
1047  | 
}  | 
|
| 77257 | 1048  | 
|
| 77436 | 1049  | 
|
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1050  | 
/* build process roles */  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1051  | 
|
| 77654 | 1052  | 
final def is_session_name(job_name: String): Boolean =  | 
1053  | 
!Long_Name.is_qualified(job_name)  | 
|
| 77648 | 1054  | 
|
| 78356 | 1055  | 
  protected final def start_build(): Unit = synchronized_database("Build_Process.start_build") {
 | 
| 78203 | 1056  | 
    for (db <- _build_database) {
 | 
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
1057  | 
Build_Process.private_data.start_build(db, build_uuid, build_context.ml_platform,  | 
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
1058  | 
build_context.sessions_structure.session_prefs)  | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1059  | 
}  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1060  | 
}  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1061  | 
|
| 78356 | 1062  | 
  protected final def stop_build(): Unit = synchronized_database("Build_Process.stop_build") {
 | 
| 78203 | 1063  | 
    for (db <- _build_database) {
 | 
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
1064  | 
Build_Process.private_data.stop_build(db, build_uuid)  | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1065  | 
}  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1066  | 
}  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1067  | 
|
| 78356 | 1068  | 
  protected final def start_worker(): Unit = synchronized_database("Build_Process.start_worker") {
 | 
| 78203 | 1069  | 
    for (db <- _build_database) {
 | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
1070  | 
_state = _state.inc_serial  | 
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
1071  | 
Build_Process.private_data.start_worker(db, worker_uuid, build_uuid, _state.serial)  | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1072  | 
}  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1073  | 
}  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1074  | 
|
| 78356 | 1075  | 
  protected final def stop_worker(): Unit = synchronized_database("Build_Process.stop_worker") {
 | 
| 78203 | 1076  | 
    for (db <- _build_database) {
 | 
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
1077  | 
Build_Process.private_data.stamp_worker(db, worker_uuid, _state.serial, stop_now = true)  | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1078  | 
}  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1079  | 
}  | 
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1080  | 
|
| 
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1081  | 
|
| 77436 | 1082  | 
/* run */  | 
| 77372 | 1083  | 
|
| 
78440
 
126a12483c67
support for Build_Cluster.Session.init (rsync + Admin/init);
 
wenzelm 
parents: 
78434 
diff
changeset
 | 
1084  | 
  def run(): Build.Results = {
 | 
| 78571 | 1085  | 
    synchronized_database("Build_Process.init") {
 | 
1086  | 
      if (build_context.master) {
 | 
|
1087  | 
_build_cluster.init()  | 
|
1088  | 
_state = init_state(_state)  | 
|
1089  | 
}  | 
|
1090  | 
_state = _state.copy(numa_nodes = Host.numa_nodes(enabled = build_context.numa_shuffling))  | 
|
| 78356 | 1091  | 
}  | 
| 
77652
 
5f706f7c624b
more thorough synchronization of internal "_state" vs. external "_database";
 
wenzelm 
parents: 
77651 
diff
changeset
 | 
1092  | 
|
| 
78529
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1093  | 
    def finished(): Boolean = synchronized_database("Build_Process.test") {
 | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1094  | 
if (!build_context.master && progress.stopped) _state.build_running.isEmpty  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1095  | 
else _state.pending.isEmpty  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1096  | 
}  | 
| 
77400
 
f3e5b3fe230e
clarified signature: more explicit "synchronized" regions;
 
wenzelm 
parents: 
77398 
diff
changeset
 | 
1097  | 
|
| 
77437
 
dcbf96acae27
clarified signature: do not expose global state to object-oriented variants;
 
wenzelm 
parents: 
77436 
diff
changeset
 | 
1098  | 
def sleep(): Unit =  | 
| 
78406
 
2ece6509ad6f
clarified options: accommodate potentially slow database connection;
 
wenzelm 
parents: 
78401 
diff
changeset
 | 
1099  | 
      Isabelle_Thread.interrupt_handler(_ => progress.stop()) { build_delay.sleep() }
 | 
| 
77437
 
dcbf96acae27
clarified signature: do not expose global state to object-oriented variants;
 
wenzelm 
parents: 
77436 
diff
changeset
 | 
1100  | 
|
| 
78394
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
1101  | 
    def check_jobs(): Boolean = synchronized_database("Build_Process.check_jobs") {
 | 
| 
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
1102  | 
val jobs = next_jobs(_state)  | 
| 
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
1103  | 
      for (name <- jobs) {
 | 
| 
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
1104  | 
        if (is_session_name(name)) {
 | 
| 78507 | 1105  | 
          if (build_context.sessions_structure.defined(name)) {
 | 
1106  | 
            _state.ancestor_results(name) match {
 | 
|
1107  | 
case Some(results) => _state = start_session(_state, name, results)  | 
|
1108  | 
case None =>  | 
|
1109  | 
build_progress.echo_warning(  | 
|
1110  | 
"Broken build job " + quote(name) + ": no ancestor results")  | 
|
1111  | 
}  | 
|
| 
78500
 
fc6d8a2895ca
more robust ancestor_results: avoid total existence failure after build_process has crashed elsewhere;
 
wenzelm 
parents: 
78440 
diff
changeset
 | 
1112  | 
}  | 
| 78507 | 1113  | 
          else build_progress.echo_warning("Broken build job " + quote(name) + ": no session info")
 | 
| 
78394
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
1114  | 
}  | 
| 
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
1115  | 
        else build_progress.echo_warning("Unsupported build job " + quote(name))
 | 
| 
77467
 
e27bc7957297
more robust: proper synchronization of transition from next_job to start_session;
 
wenzelm 
parents: 
77466 
diff
changeset
 | 
1116  | 
}  | 
| 
78394
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
1117  | 
jobs.nonEmpty  | 
| 
77467
 
e27bc7957297
more robust: proper synchronization of transition from next_job to start_session;
 
wenzelm 
parents: 
77466 
diff
changeset
 | 
1118  | 
}  | 
| 
 
e27bc7957297
more robust: proper synchronization of transition from next_job to start_session;
 
wenzelm 
parents: 
77466 
diff
changeset
 | 
1119  | 
|
| 77335 | 1120  | 
    if (finished()) {
 | 
1121  | 
      progress.echo_warning("Nothing to build")
 | 
|
| 
78440
 
126a12483c67
support for Build_Cluster.Session.init (rsync + Admin/init);
 
wenzelm 
parents: 
78434 
diff
changeset
 | 
1122  | 
Build.Results(build_context)  | 
| 77335 | 1123  | 
}  | 
1124  | 
    else {
 | 
|
| 
77579
 
69d3547206db
clarified signature: prefer Build_Process.Context for parameters;
 
wenzelm 
parents: 
77578 
diff
changeset
 | 
1125  | 
if (build_context.master) start_build()  | 
| 78241 | 1126  | 
start_worker()  | 
| 
78434
 
b4ec7ea073da
clarified signature: delegate policies to Build_Cluster implementation, potentially provided by Build.Engine via Build_Process.open_build_cluster;
 
wenzelm 
parents: 
78430 
diff
changeset
 | 
1127  | 
_build_cluster.start()  | 
| 
77578
 
149d48a4801b
support for "isabelle build -j0": require external workers to make progress;
 
wenzelm 
parents: 
77561 
diff
changeset
 | 
1128  | 
|
| 
78434
 
b4ec7ea073da
clarified signature: delegate policies to Build_Cluster implementation, potentially provided by Build.Engine via Build_Process.open_build_cluster;
 
wenzelm 
parents: 
78430 
diff
changeset
 | 
1129  | 
      if (build_context.master && !build_context.worker_active && _build_cluster.active()) {
 | 
| 78252 | 1130  | 
        build_progress.echo("Waiting for external workers ...")
 | 
| 
77580
 
32f9e75c92e9
clarified worker state: always maintain database content via worker_uuid;
 
wenzelm 
parents: 
77579 
diff
changeset
 | 
1131  | 
}  | 
| 
77578
 
149d48a4801b
support for "isabelle build -j0": require external workers to make progress;
 
wenzelm 
parents: 
77561 
diff
changeset
 | 
1132  | 
|
| 77538 | 1133  | 
      try {
 | 
1134  | 
        while (!finished()) {
 | 
|
| 78356 | 1135  | 
          synchronized_database("Build_Process.main") {
 | 
| 77639 | 1136  | 
if (progress.stopped) _state.stop_running()  | 
| 77310 | 1137  | 
|
| 77649 | 1138  | 
            for (job <- _state.finished_running()) {
 | 
| 
78529
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1139  | 
              job.join_build match {
 | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1140  | 
case None =>  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1141  | 
_state = _state.remove_running(job.name)  | 
| 78530 | 1142  | 
case Some(result) =>  | 
| 
78529
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1143  | 
val result_name = (job.name, worker_uuid, build_uuid)  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1144  | 
_state = _state.  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1145  | 
remove_pending(job.name).  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1146  | 
remove_running(job.name).  | 
| 78530 | 1147  | 
make_result(result_name,  | 
1148  | 
result.process_result,  | 
|
1149  | 
result.output_shasum,  | 
|
| 
78529
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1150  | 
node_info = job.node_info)  | 
| 
 
0e79fa88cab6
build_worker is stopped independently from master build_process;
 
wenzelm 
parents: 
78510 
diff
changeset
 | 
1151  | 
}  | 
| 77538 | 1152  | 
}  | 
1153  | 
}  | 
|
1154  | 
||
| 
78394
 
761d12b043d0
proper running limit, based on this worker process;
 
wenzelm 
parents: 
78393 
diff
changeset
 | 
1155  | 
if (!check_jobs()) sleep()  | 
| 77396 | 1156  | 
}  | 
| 77310 | 1157  | 
}  | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1158  | 
      finally {
 | 
| 
78434
 
b4ec7ea073da
clarified signature: delegate policies to Build_Cluster implementation, potentially provided by Build.Engine via Build_Process.open_build_cluster;
 
wenzelm 
parents: 
78430 
diff
changeset
 | 
1159  | 
_build_cluster.stop()  | 
| 
77580
 
32f9e75c92e9
clarified worker state: always maintain database content via worker_uuid;
 
wenzelm 
parents: 
77579 
diff
changeset
 | 
1160  | 
stop_worker()  | 
| 
77579
 
69d3547206db
clarified signature: prefer Build_Process.Context for parameters;
 
wenzelm 
parents: 
77578 
diff
changeset
 | 
1161  | 
if (build_context.master) stop_build()  | 
| 
77546
 
9b9179cda155
clarified build process roles: "worker" vs. "build";
 
wenzelm 
parents: 
77545 
diff
changeset
 | 
1162  | 
}  | 
| 
77467
 
e27bc7957297
more robust: proper synchronization of transition from next_job to start_session;
 
wenzelm 
parents: 
77466 
diff
changeset
 | 
1163  | 
|
| 78356 | 1164  | 
      synchronized_database("Build_Process.result") {
 | 
| 
78440
 
126a12483c67
support for Build_Cluster.Session.init (rsync + Admin/init);
 
wenzelm 
parents: 
78434 
diff
changeset
 | 
1165  | 
val results = for ((name, result) <- _state.results) yield name -> result.process_result  | 
| 
 
126a12483c67
support for Build_Cluster.Session.init (rsync + Admin/init);
 
wenzelm 
parents: 
78434 
diff
changeset
 | 
1166  | 
Build.Results(build_context, results = results, other_rc = _build_cluster.rc)  | 
| 77257 | 1167  | 
}  | 
1168  | 
}  | 
|
1169  | 
}  | 
|
| 
77659
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1170  | 
|
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1171  | 
|
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1172  | 
/* snapshot */  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1173  | 
|
| 78356 | 1174  | 
  def snapshot(): Build_Process.Snapshot = synchronized_database("Build_Process.snapshot") {
 | 
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
1175  | 
val (builds, workers) =  | 
| 78203 | 1176  | 
      _build_database match {
 | 
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
1177  | 
case None => (Nil, Nil)  | 
| 
77659
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1178  | 
case Some(db) =>  | 
| 
78396
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
1179  | 
(Build_Process.private_data.read_builds(db),  | 
| 
 
7853d9072d1b
renamed object Data to private_data, to emphasize its intended scope (but it is publicly accessible in the database);
 
wenzelm 
parents: 
78394 
diff
changeset
 | 
1180  | 
Build_Process.private_data.read_workers(db))  | 
| 
77659
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1181  | 
}  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1182  | 
Build_Process.Snapshot(  | 
| 77660 | 1183  | 
builds = builds,  | 
| 
77659
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1184  | 
workers = workers,  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1185  | 
sessions = _state.sessions,  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1186  | 
pending = _state.pending,  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1187  | 
running = _state.running,  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1188  | 
results = _state.results)  | 
| 
 
d7eb6a4522b8
more explicit snapshot of "_state" and "_database";
 
wenzelm 
parents: 
77658 
diff
changeset
 | 
1189  | 
}  | 
| 
78156
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
1190  | 
|
| 
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
1191  | 
|
| 
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
1192  | 
/* toString */  | 
| 
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
1193  | 
|
| 
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
1194  | 
override def toString: String =  | 
| 
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
1195  | 
"Build_Process(worker_uuid = " + quote(worker_uuid) + ", build_uuid = " + quote(build_uuid) +  | 
| 
 
da5cc332ded3
prefer Database_Progress, which is more robust (amending afb1a19307c4);
 
wenzelm 
parents: 
78154 
diff
changeset
 | 
1196  | 
if_proper(build_context.master, ", master = true") + ")"  | 
| 77238 | 1197  | 
}  |