Mercurial > hg > dml-open-cliopatria
diff cpack/dml/applications/memo_ui.pl @ 0:718306e29690 tip
commiting public release
author | Daniel Wolff |
---|---|
date | Tue, 09 Feb 2016 21:05:06 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cpack/dml/applications/memo_ui.pl Tue Feb 09 21:05:06 2016 +0100 @@ -0,0 +1,159 @@ +/* Part of DML (Digital Music Laboratory) + Copyright 2014-2015 Samer Abdallah, University of London + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +:- module(memo_ui, []). + +/** <module> UI for viewing memoised functions +*/ +:- use_module(library(http/html_write)). +:- use_module(library(http/html_head)). +:- use_module(library(http/http_dispatch)). +:- use_module(library(http/http_parameters)). +:- use_module(library(decoration)). +:- use_module(library(htmlutils)). +:- use_module(library(memo)). +:- use_module(library(async)). +:- use_module(library(listutils)). +:- use_module(library(httpfiles)). +:- use_module(components(table)). +:- use_module(components(icons)). +:- use_module(cliopatria(hooks)). + +:- set_prolog_flag(double_quotes,string). + +:- http_handler(root(dml/memo/view), memo_view, []). +:- http_handler(root(dml/jobs/view), job_view, []). +:- http_handler(root(dml/jobs/cancel), cancel_job, []). + +decoration:resource_view(URI,_) --> + { rdf(URI,rdf:type,memo:'Function'), !, + uripattern:pattern_uri(\func(Mod,Pred,Arity),URI), + format(string(Name),"~w:~w/~d",[Mod,Pred,Arity]), + http_link_to_id(pldoc_object,[object=Name],DocLink), + http_link_to_id(memo_view,[uri(URI)],ViewURL) + }, + html_requires(font_awesome), + html( [ a(href=ViewURL, [\icon(table)," View"]), ' ' + , a(href=DocLink, [\icon(book)," Documentation"]) + ]). + +decoration:resource_decoration(URI,Link) --> + { rdf(URI,rdf:type,memo:'Function'), !, + % uripattern:pattern_uri(dml: \func(Mod,Pred,Arity),URI), + % format(string(Name),"~w:~w/~d",[Mod,Pred,Arity]), + % http_link_to_id(pldoc_object,[object=Name],DocLink), + http_link_to_id(memo_view,[uri=URI],ViewLink) + }, + html_requires(font_awesome), + html( span( [ a(href(ViewLink),\icon(table)), &(nbsp) + % , a(href(DocLink),\icon(book)), &(nbsp) + , \Link ])). + +memo_view(Request) :- + http_parameters(Request, + [ uri(URI, [ optional(false), description("URI of CSV file")]) + , page(Page, [ nonneg, default(1) ]) + , limit(Limit, [ nonneg, default(50) ]) + ]), + format(string(FullTitle),"View for ~w",[URI]), + uripattern:pattern_uri(\func(Mod,Pred,Arity),URI), + length(Args,Arity), + Head =.. [Pred|Args], + aggregate_all(count,browse(Mod:Head),Total), + ( Total=0 + -> Content=p("This function has no successful memoised computations.") + ; Offset is Limit*(Page-1), + Pages is ceil(Total/Limit), + insist(Page=<Pages), + % insist(Page=Pages -> Rows1=Rows2; take(Limit,Rows1,Rows2)), + Content = [ \paginator(memo_view-[uri(URI),limit(Limit)],Page,Pages) + , \table_from_goal(goal_row(limit(Limit,offset(Offset,browse(Mod:Head))),Args),[]) + , \paginator(memo_view-[uri(URI),limit(Limit)],Page,Pages) + ] + ), + reply_html_page(cliopatria(demo), [title(FullTitle)], [ h1(FullTitle) | Content ], [unstable]). + +cancel_job(Request) :- + insist(user_db:logged_on(_),not_authorised(cancel_job)), + http_parameters(Request, + [ pool(Pool, [ atom, optional(false) ]) + , id(Id, [ atom, optional(false) ]) + , return_to(ReturnTo, [ atom, default(_) ]) + ]), + async_cancel(Pool,Id), % !!! this could throw an error + (var(ReturnTo) -> member(referer(ReturnTo),Request); true), + debug(async,'Cancelling job ~w:~w, returning to ~w',[Pool,Id,ReturnTo]), + http_redirect(see_other,ReturnTo,Request). + +job_view(Request) :- + http_parameters(Request, [pool(Pool, [atom, default(vis_cla)])]), + format(string(FullTitle),"Current jobs in thread pool ~w",[Pool]), + findall(job(Goal,ID,TSub,Status),async_current_job(Pool,Goal,ID,TSub,Status),Jobs), + reply_html_page(cliopatria(demo), [title(FullTitle)], + [h1(FullTitle), \job_tables(Pool,Jobs)], + [unstable]). + +job_tables(Pool,Jobs) --> + {partition(is_waiting, Jobs, Waiting, Running)}, + ( {Running=[]} -> html(h3("No jobs running.")) + ; html( [ h3("Running jobs") + , \table_from_goal(running_job(Pool,Running), + [headings(['Started','Elapsed','Progress','Goal','Actions'])]) + ]) + ), + ( {Waiting=[]} -> html(h3("No jobs waiting.")) + ; html( [ h3("Waiting jobs") + , \table_from_goal(waiting_job(Pool,Waiting), + [headings(['Position','Submitted','Goal','Actions'])]) + ]) + ). + + +is_waiting(job(_,_,_,waiting(_))). + +waiting_job(Pool,Jobs,[Pos,TSubmit,GoalCell,a(href(Cancel),cancel)]) :- + member(job(Goal,ID,TSubmit,waiting(Pos)),Jobs), % !!! add submit time to table? + http_link_to_id(cancel_job,[pool=Pool,id=ID],Cancel), + goal_cell(Goal,GoalCell). +running_job(Pool,Jobs,[StartS,ElapsedS,ProgressS,GoalCell,a(href(Cancel),cancel)]) :- + member(job(Goal,ID,_TSubmit,running(Thread,Start)),Jobs), + http_link_to_id(cancel_job,[pool=Pool,id=ID],Cancel), + format_time(string(StartS),'%FT%T%:z',Start), + debug(async,'Getting running job progress from thread ~w...',[Thread]), + catch(( async_thread_progress(Thread,[summary],TNow,[Progress]), + progress_string(Progress,ProgressS), + Elapsed is TNow-Start, format(string(ElapsedS),'~2f',[Elapsed]) + ), Ex, ( debug(async,'Failed to get job progress ~q',[Ex]), + ElapsedS="N/A", ProgressS="ENDED")), + copy_term(Goal,Goal1), + numbervars(Goal1,0,_), + goal_cell(Goal1,GoalCell). + +goal_cell(Mod:Head,a(href(URL),GoalS)) :- + functor(Head,Pred,Arity), + uripattern:pattern_uri(\func(Mod,Pred,Arity),URI), + http_link_to_id(list_resource,[r(URI)],URL), + term_cell(Mod:Head,GoalS). + +progress_string(Progress,String) :- memberchk(stepwise(_Desc,Done/Total), Progress), !, format(string(String),'~d/~d',[Done,Total]). +progress_string(_Terms, "-"). + +goal_row(Pred,Vals,Cells) :- call(Pred), maplist(term_cell,Vals,Cells). +term_cell(Term,Cell) :- + with_output_to(string(Cell),write_term(Term,[quoted(true),max_depth(6),numbervars(true)])). +