src/Pure/Tools/server_commands.scala
changeset 75393 87ebf5a50283
parent 74306 a117c076aa22
child 75394 42267c650205
equal deleted inserted replaced
75388:b3ca4a6ed74b 75393:87ebf5a50283
     5 */
     5 */
     6 
     6 
     7 package isabelle
     7 package isabelle
     8 
     8 
     9 
     9 
    10 object Server_Commands
    10 object Server_Commands {
    11 {
       
    12   def default_preferences: String = Options.read_prefs()
    11   def default_preferences: String = Options.read_prefs()
    13 
    12 
    14   object Help extends Server.Command("help")
    13   object Help extends Server.Command("help") {
    15   {
       
    16     override val command_body: Server.Command_Body =
    14     override val command_body: Server.Command_Body =
    17       { case (context, ()) => context.command_list }
    15       { case (context, ()) => context.command_list }
    18   }
    16   }
    19 
    17 
    20   object Echo extends Server.Command("echo")
    18   object Echo extends Server.Command("echo") {
    21   {
       
    22     override val command_body: Server.Command_Body =
    19     override val command_body: Server.Command_Body =
    23       { case (_, t) => t }
    20       { case (_, t) => t }
    24   }
    21   }
    25 
    22 
    26   object Cancel extends Server.Command("cancel")
    23   object Cancel extends Server.Command("cancel") {
    27   {
       
    28     sealed case class Args(task: UUID.T)
    24     sealed case class Args(task: UUID.T)
    29 
    25 
    30     def unapply(json: JSON.T): Option[Args] =
    26     def unapply(json: JSON.T): Option[Args] =
    31       for { task <- JSON.uuid(json, "task") }
    27       for { task <- JSON.uuid(json, "task") }
    32       yield Args(task)
    28       yield Args(task)
    33 
    29 
    34     override val command_body: Server.Command_Body =
    30     override val command_body: Server.Command_Body =
    35       { case (context, Cancel(args)) => context.cancel_task(args.task) }
    31       { case (context, Cancel(args)) => context.cancel_task(args.task) }
    36   }
    32   }
    37 
    33 
    38   object Shutdown extends Server.Command("shutdown")
    34   object Shutdown extends Server.Command("shutdown") {
    39   {
       
    40     override val command_body: Server.Command_Body =
    35     override val command_body: Server.Command_Body =
    41       { case (context, ()) => context.server.shutdown() }
    36       { case (context, ()) => context.server.shutdown() }
    42   }
    37   }
    43 
    38 
    44   object Session_Build extends Server.Command("session_build")
    39   object Session_Build extends Server.Command("session_build") {
    45   {
       
    46     sealed case class Args(
    40     sealed case class Args(
    47       session: String,
    41       session: String,
    48       preferences: String = default_preferences,
    42       preferences: String = default_preferences,
    49       options: List[String] = Nil,
    43       options: List[String] = Nil,
    50       dirs: List[String] = Nil,
    44       dirs: List[String] = Nil,
    63       yield {
    57       yield {
    64         Args(session, preferences = preferences, options = options, dirs = dirs,
    58         Args(session, preferences = preferences, options = options, dirs = dirs,
    65           include_sessions = include_sessions, verbose = verbose)
    59           include_sessions = include_sessions, verbose = verbose)
    66       }
    60       }
    67 
    61 
    68     def command(args: Args, progress: Progress = new Progress)
    62     def command(
    69       : (JSON.Object.T, Build.Results, Options, Sessions.Base_Info) =
    63       args: Args,
    70     {
    64       progress: Progress = new Progress
       
    65     ) : (JSON.Object.T, Build.Results, Options, Sessions.Base_Info) = {
    71       val options = Options.init(prefs = args.preferences, opts = args.options)
    66       val options = Options.init(prefs = args.preferences, opts = args.options)
    72       val dirs = args.dirs.map(Path.explode)
    67       val dirs = args.dirs.map(Path.explode)
    73 
    68 
    74       val base_info =
    69       val base_info =
    75         Sessions.base_info(options, args.session, progress = progress, dirs = dirs,
    70         Sessions.base_info(options, args.session, progress = progress, dirs = dirs,
    91       val results_json =
    86       val results_json =
    92         JSON.Object(
    87         JSON.Object(
    93           "ok" -> results.ok,
    88           "ok" -> results.ok,
    94           "return_code" -> results.rc,
    89           "return_code" -> results.rc,
    95           "sessions" ->
    90           "sessions" ->
    96             results.sessions.toList.sortBy(sessions_order).map(session =>
    91             results.sessions.toList.sortBy(sessions_order).map(session => {
    97               {
    92               val result = results(session)
    98                 val result = results(session)
    93               JSON.Object(
    99                 JSON.Object(
    94                 "session" -> session,
   100                   "session" -> session,
    95                 "ok" -> result.ok,
   101                   "ok" -> result.ok,
    96                 "return_code" -> result.rc,
   102                   "return_code" -> result.rc,
    97                 "timeout" -> result.timeout,
   103                   "timeout" -> result.timeout,
    98                 "timing" -> result.timing.json)
   104                   "timing" -> result.timing.json)
    99             }))
   105               }))
       
   106 
   100 
   107       if (results.ok) (results_json, results, options, base_info)
   101       if (results.ok) (results_json, results, options, base_info)
   108       else {
   102       else {
   109         throw new Server.Error("Session build failed: " + Process_Result.RC.print(results.rc),
   103         throw new Server.Error("Session build failed: " + Process_Result.RC.print(results.rc),
   110           results_json)
   104           results_json)
   114     override val command_body: Server.Command_Body =
   108     override val command_body: Server.Command_Body =
   115       { case (context, Session_Build(args)) =>
   109       { case (context, Session_Build(args)) =>
   116         context.make_task(task => Session_Build.command(args, progress = task.progress)._1) }
   110         context.make_task(task => Session_Build.command(args, progress = task.progress)._1) }
   117   }
   111   }
   118 
   112 
   119   object Session_Start extends Server.Command("session_start")
   113   object Session_Start extends Server.Command("session_start") {
   120   {
       
   121     sealed case class Args(
   114     sealed case class Args(
   122       build: Session_Build.Args,
   115       build: Session_Build.Args,
   123       print_mode: List[String] = Nil)
   116       print_mode: List[String] = Nil)
   124 
   117 
   125     def unapply(json: JSON.T): Option[Args] =
   118     def unapply(json: JSON.T): Option[Args] =
   127         build <- Session_Build.unapply(json)
   120         build <- Session_Build.unapply(json)
   128         print_mode <- JSON.strings_default(json, "print_mode")
   121         print_mode <- JSON.strings_default(json, "print_mode")
   129       }
   122       }
   130       yield Args(build = build, print_mode = print_mode)
   123       yield Args(build = build, print_mode = print_mode)
   131 
   124 
   132     def command(args: Args, progress: Progress = new Progress, log: Logger = No_Logger)
   125     def command(
   133       : (JSON.Object.T, (UUID.T, Headless.Session)) =
   126       args: Args,
   134     {
   127       progress: Progress = new Progress,
       
   128       log: Logger = No_Logger
       
   129     ) : (JSON.Object.T, (UUID.T, Headless.Session)) = {
   135       val (_, _, options, base_info) =
   130       val (_, _, options, base_info) =
   136         try { Session_Build.command(args.build, progress = progress) }
   131         try { Session_Build.command(args.build, progress = progress) }
   137         catch { case exn: Server.Error => error(exn.message) }
   132         catch { case exn: Server.Error => error(exn.message) }
   138 
   133 
   139       val resources = Headless.Resources(options, base_info, log = log)
   134       val resources = Headless.Resources(options, base_info, log = log)
   150       (res, id -> session)
   145       (res, id -> session)
   151     }
   146     }
   152 
   147 
   153     override val command_body: Server.Command_Body =
   148     override val command_body: Server.Command_Body =
   154       { case (context, Session_Start(args)) =>
   149       { case (context, Session_Start(args)) =>
   155           context.make_task(task =>
   150           context.make_task(task => {
   156           {
       
   157             val (res, entry) =
   151             val (res, entry) =
   158               Session_Start.command(args, progress = task.progress, log = context.server.log)
   152               Session_Start.command(args, progress = task.progress, log = context.server.log)
   159             context.server.add_session(entry)
   153             context.server.add_session(entry)
   160             res
   154             res
   161           })
   155           })
   162       }
   156       }
   163   }
   157   }
   164 
   158 
   165   object Session_Stop extends Server.Command("session_stop")
   159   object Session_Stop extends Server.Command("session_stop") {
   166   {
       
   167     def unapply(json: JSON.T): Option[UUID.T] =
   160     def unapply(json: JSON.T): Option[UUID.T] =
   168       JSON.uuid(json, "session_id")
   161       JSON.uuid(json, "session_id")
   169 
   162 
   170     def command(session: Headless.Session): (JSON.Object.T, Process_Result) =
   163     def command(session: Headless.Session): (JSON.Object.T, Process_Result) = {
   171     {
       
   172       val result = session.stop()
   164       val result = session.stop()
   173       val result_json = JSON.Object("ok" -> result.ok, "return_code" -> result.rc)
   165       val result_json = JSON.Object("ok" -> result.ok, "return_code" -> result.rc)
   174 
   166 
   175       if (result.ok) (result_json, result)
   167       if (result.ok) (result_json, result)
   176       else throw new Server.Error("Session shutdown failed: " + result.print_rc, result_json)
   168       else throw new Server.Error("Session shutdown failed: " + result.print_rc, result_json)
   184           Session_Stop.command(session)._1
   176           Session_Stop.command(session)._1
   185         })
   177         })
   186       }
   178       }
   187   }
   179   }
   188 
   180 
   189   object Use_Theories extends Server.Command("use_theories")
   181   object Use_Theories extends Server.Command("use_theories") {
   190   {
       
   191     sealed case class Args(
   182     sealed case class Args(
   192       session_id: UUID.T,
   183       session_id: UUID.T,
   193       theories: List[String],
   184       theories: List[String],
   194       master_dir: String = "",
   185       master_dir: String = "",
   195       pretty_margin: Double = Pretty.default_margin,
   186       pretty_margin: Double = Pretty.default_margin,
   223       }
   214       }
   224 
   215 
   225     def command(args: Args,
   216     def command(args: Args,
   226       session: Headless.Session,
   217       session: Headless.Session,
   227       id: UUID.T = UUID.random(),
   218       id: UUID.T = UUID.random(),
   228       progress: Progress = new Progress): (JSON.Object.T, Headless.Use_Theories_Result) =
   219       progress: Progress = new Progress
   229     {
   220     ): (JSON.Object.T, Headless.Use_Theories_Result) = {
   230       val result =
   221       val result =
   231         session.use_theories(args.theories, master_dir = args.master_dir,
   222         session.use_theories(args.theories, master_dir = args.master_dir,
   232           check_delay = args.check_delay.getOrElse(session.default_check_delay),
   223           check_delay = args.check_delay.getOrElse(session.default_check_delay),
   233           check_limit = args.check_limit.getOrElse(session.default_check_limit),
   224           check_limit = args.check_limit.getOrElse(session.default_check_limit),
   234           watchdog_timeout = args.watchdog_timeout.getOrElse(session.default_watchdog_timeout),
   225           watchdog_timeout = args.watchdog_timeout.getOrElse(session.default_watchdog_timeout),
   238           id = id, progress = progress)
   229           id = id, progress = progress)
   239 
   230 
   240       def output_text(text: String): String =
   231       def output_text(text: String): String =
   241         Symbol.output(args.unicode_symbols, text)
   232         Symbol.output(args.unicode_symbols, text)
   242 
   233 
   243       def output_message(tree: XML.Tree, pos: Position.T): JSON.Object.T =
   234       def output_message(tree: XML.Tree, pos: Position.T): JSON.Object.T = {
   244       {
       
   245         val position = "pos" -> Position.JSON(pos)
   235         val position = "pos" -> Position.JSON(pos)
   246         tree match {
   236         tree match {
   247           case XML.Text(msg) => Server.Reply.message(output_text(msg)) + position
   237           case XML.Text(msg) => Server.Reply.message(output_text(msg)) + position
   248           case elem: XML.Elem =>
   238           case elem: XML.Elem =>
   249             val msg = XML.content(Pretty.formatted(List(elem), margin = args.pretty_margin))
   239             val msg = XML.content(Pretty.formatted(List(elem), margin = args.pretty_margin))
   285       (result_json, result)
   275       (result_json, result)
   286     }
   276     }
   287 
   277 
   288     override val command_body: Server.Command_Body =
   278     override val command_body: Server.Command_Body =
   289       { case (context, Use_Theories(args)) =>
   279       { case (context, Use_Theories(args)) =>
   290         context.make_task(task =>
   280         context.make_task(task => {
   291         {
       
   292           val session = context.server.the_session(args.session_id)
   281           val session = context.server.the_session(args.session_id)
   293           Use_Theories.command(args, session, id = task.id, progress = task.progress)._1
   282           Use_Theories.command(args, session, id = task.id, progress = task.progress)._1
   294         })
   283         })
   295       }
   284       }
   296   }
   285   }
   297 
   286 
   298   object Purge_Theories extends Server.Command("purge_theories")
   287   object Purge_Theories extends Server.Command("purge_theories") {
   299   {
       
   300     sealed case class Args(
   288     sealed case class Args(
   301       session_id: UUID.T,
   289       session_id: UUID.T,
   302       theories: List[String] = Nil,
   290       theories: List[String] = Nil,
   303       master_dir: String = "",
   291       master_dir: String = "",
   304       all: Boolean = false)
   292       all: Boolean = false)
   310         master_dir <- JSON.string_default(json, "master_dir")
   298         master_dir <- JSON.string_default(json, "master_dir")
   311         all <- JSON.bool_default(json, "all")
   299         all <- JSON.bool_default(json, "all")
   312       }
   300       }
   313       yield { Args(session_id, theories = theories, master_dir = master_dir, all = all) }
   301       yield { Args(session_id, theories = theories, master_dir = master_dir, all = all) }
   314 
   302 
   315     def command(args: Args, session: Headless.Session)
   303     def command(
   316       : (JSON.Object.T, (List[Document.Node.Name], List[Document.Node.Name])) =
   304       args: Args,
   317     {
   305       session: Headless.Session
       
   306     ) : (JSON.Object.T, (List[Document.Node.Name], List[Document.Node.Name])) = {
   318       val (purged, retained) =
   307       val (purged, retained) =
   319         session.purge_theories(
   308         session.purge_theories(
   320           theories = args.theories, master_dir = args.master_dir, all = args.all)
   309           theories = args.theories, master_dir = args.master_dir, all = args.all)
   321 
   310 
   322       val result_json =
   311       val result_json =