Scribunto: Hack fix for stopping long-running threads [#737]

staging
gnosygnu 4 years ago
parent b4516f5060
commit b87e4d07cb

@ -1,23 +1,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.threads; import gplx.*; import gplx.core.*;
import java.lang.*;
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.threads;
import gplx.Cancelable;
import gplx.Cancelable_;
import gplx.Err_;
import gplx.GfoMsg;
import gplx.GfoMsg_;
import gplx.Gfo_invk;
import gplx.Gfo_invk_;
import gplx.Gfo_log_;
public class Thread_adp implements Runnable {
private final String thread_name; private final Cancelable cxl; private final boolean cxlable;
private final Gfo_invk invk_itm; private final String invk_cmd; private final GfoMsg invk_msg;
private final String thread_name; private final Cancelable cxl; private final boolean cxlable;
private final Gfo_invk invk_itm; private final String invk_cmd; private final GfoMsg invk_msg;
private Thread thread;
@gplx.Internal protected Thread_adp(String thread_name, Cancelable cxl, Gfo_invk invk_itm, String invk_cmd, GfoMsg invk_msg) {
this.thread_name = thread_name; this.cxl = cxl; this.cxlable = cxl != Cancelable_.Never;
@ -28,6 +37,7 @@ public class Thread_adp implements Runnable {
public boolean Thread__cancelable() {return cxlable;}
public boolean Thread__is_alive() {return thread == null ? false : thread.isAlive();}
public void Thread__interrupt() {thread.interrupt();}
public void Thread__stop() {thread.stop();}
public void run() {
try {
Gfo_invk_.Invk_by_msg(invk_itm, invk_cmd, invk_msg);
@ -37,8 +47,8 @@ public class Thread_adp implements Runnable {
}
}
public void Thread__start() {
this.thread = (thread_name == null) ? new Thread(this) : new Thread(this, thread_name);
this.thread = (thread_name == null) ? new Thread(this) : new Thread(this, thread_name);
thread.start();
}
public static final Thread_adp Noop = new Thread_adp(Thread_adp_.Name_null, Cancelable_.Never, Gfo_invk_.Noop, "", GfoMsg_.Null);
}
public static final Thread_adp Noop = new Thread_adp(Thread_adp_.Name_null, Cancelable_.Never, Gfo_invk_.Noop, "", GfoMsg_.Null);
}

@ -1,28 +1,36 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.threads; import gplx.*; import gplx.core.*;
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.threads;
import gplx.Cancelable;
import gplx.Cancelable_;
import gplx.Err_;
import gplx.GfoMsg;
import gplx.GfoMsg_;
import gplx.Gfo_invk;
public class Thread_adp_ {
public static void Sleep(int milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
throw Err_.new_exc(e, "core", "thread interrupted", "milliseconds", milliseconds);
}
}
}
public static Thread_adp Start_by_key(String thread_name, Gfo_invk invk_itm, String invk_cmd) {return Start(thread_name, Cancelable_.Never, invk_itm, invk_cmd , GfoMsg_.new_cast_(invk_cmd));}
public static Thread_adp Start_by_key(String thread_name, Gfo_invk invk_itm, String invk_cmd) {return Start(thread_name, Cancelable_.Never, invk_itm, invk_cmd , GfoMsg_.new_cast_(invk_cmd));}
public static Thread_adp Start_by_val(String thread_name, Gfo_invk invk_itm, String invk_cmd, Object val) {return Start(thread_name, Cancelable_.Never, invk_itm, invk_cmd , GfoMsg_.new_cast_(invk_cmd).Add("v", val));}
public static Thread_adp Start_by_msg(String thread_name, Gfo_invk invk_itm, GfoMsg invk_msg) {return Start(thread_name, Cancelable_.Never, invk_itm, invk_msg.Key() , invk_msg);}
public static Thread_adp Start_by_key(String thread_name, Cancelable cxl, Gfo_invk invk_itm, String invk_cmd) {return Start(thread_name, cxl, invk_itm, invk_cmd , GfoMsg_.new_cast_(invk_cmd));}

@ -24,6 +24,7 @@ import gplx.xowa.wikis.nss.*;
import gplx.xowa.htmls.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.logs.*; import gplx.xowa.parsers.tmpls.*;
import gplx.xowa.xtns.pfuncs.*;
public class Scrib_invoke_func extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_invoke;}
@Override public Pf_func New(int id, byte[] name) {return new Scrib_invoke_func().Name_(name);}
@ -72,11 +73,15 @@ public class Scrib_invoke_func extends Pf_func_base {
InvokeInvoker invoker = new InvokeInvoker(core, wiki, ctx, src, caller, self, bfr, mod_name, mod_raw, fnc_name);
Thread_adp thread = Thread_adp_.Start_by_key("scribunto", invoker, "default");
while (thread.Thread__is_alive()) {
Thread_adp_.Sleep(10);
if (System_.Ticks__elapsed_in_frac(timeBgn) > timeoutInMs) {
thread.Thread__interrupt();
throw Err_.new_wo_type(String_.Format("scribunto timeout: page={0} mod={1} func={2} time={3}", ctx.Page_url_str(), mod_name, fnc_name, timeoutInMs));
thread.Thread__stop();
invoker.Exc = Err_.new_wo_type(String_.Format("scribunto timeout: page={0} mod={1} func={2} time={3}", ctx.Page_url_str(), mod_name, fnc_name, timeoutInMs));
}
}
if (invoker.Exc != null) {
throw invoker.Exc;
}
if (invoke_wkr != null)
invoke_wkr.Eval_end(ctx.Page(), mod_name, fnc_name, log_time_bgn);
}
@ -131,8 +136,14 @@ public class Scrib_invoke_func extends Pf_func_base {
this.mod_raw = mod_raw;
this.fnc_name = fnc_name;
}
public Exception Exc;
public Object Invk(GfsCtx gctx, int ikey, String k, GfoMsg m) {
core.Invoke(wiki, ctx, src, caller, self, bfr, mod_name, mod_raw, fnc_name);
try {
core.Invoke(wiki, ctx, src, caller, self, bfr, mod_name, mod_raw, fnc_name);
}
catch (Exception exc) {
this.Exc = exc;
}
return null;
}
}

Loading…
Cancel
Save