mirror of
https://github.com/gnosygnu/xowa.git
synced 2024-09-28 14:30:51 +00:00
Scribunto: Hack fix for stopping long-running threads [#737]
This commit is contained in:
parent
b4516f5060
commit
b87e4d07cb
@ -1,23 +1,32 @@
|
|||||||
/*
|
/*
|
||||||
XOWA: the XOWA Offline Wiki Application
|
XOWA: the XOWA Offline Wiki Application
|
||||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||||
|
|
||||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
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.
|
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
|
You may use XOWA according to either of these licenses as is most appropriate
|
||||||
for your project on a case-by-case basis.
|
for your project on a case-by-case basis.
|
||||||
|
|
||||||
The terms of each license can be found in the source code repository:
|
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
|
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||||
*/
|
*/
|
||||||
package gplx.core.threads; import gplx.*; import gplx.core.*;
|
package gplx.core.threads;
|
||||||
import java.lang.*;
|
|
||||||
|
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 {
|
public class Thread_adp implements Runnable {
|
||||||
private final String thread_name; private final Cancelable cxl; private final boolean cxlable;
|
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 Gfo_invk invk_itm; private final String invk_cmd; private final GfoMsg invk_msg;
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
@gplx.Internal protected Thread_adp(String thread_name, Cancelable cxl, Gfo_invk invk_itm, String invk_cmd, GfoMsg invk_msg) {
|
@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;
|
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__cancelable() {return cxlable;}
|
||||||
public boolean Thread__is_alive() {return thread == null ? false : thread.isAlive();}
|
public boolean Thread__is_alive() {return thread == null ? false : thread.isAlive();}
|
||||||
public void Thread__interrupt() {thread.interrupt();}
|
public void Thread__interrupt() {thread.interrupt();}
|
||||||
|
public void Thread__stop() {thread.stop();}
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Gfo_invk_.Invk_by_msg(invk_itm, invk_cmd, invk_msg);
|
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() {
|
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();
|
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
|
XOWA: the XOWA Offline Wiki Application
|
||||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||||
|
|
||||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
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.
|
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
|
You may use XOWA according to either of these licenses as is most appropriate
|
||||||
for your project on a case-by-case basis.
|
for your project on a case-by-case basis.
|
||||||
|
|
||||||
The terms of each license can be found in the source code repository:
|
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
|
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||||
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||||
*/
|
*/
|
||||||
package gplx.core.threads; import gplx.*; import gplx.core.*;
|
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 class Thread_adp_ {
|
||||||
public static void Sleep(int milliseconds) {
|
public static void Sleep(int milliseconds) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(milliseconds);
|
Thread.sleep(milliseconds);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw Err_.new_exc(e, "core", "thread interrupted", "milliseconds", milliseconds);
|
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_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_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));}
|
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.htmls.*;
|
||||||
import gplx.xowa.parsers.*; import gplx.xowa.parsers.logs.*; import gplx.xowa.parsers.tmpls.*;
|
import gplx.xowa.parsers.*; import gplx.xowa.parsers.logs.*; import gplx.xowa.parsers.tmpls.*;
|
||||||
import gplx.xowa.xtns.pfuncs.*;
|
import gplx.xowa.xtns.pfuncs.*;
|
||||||
|
|
||||||
public class Scrib_invoke_func extends Pf_func_base {
|
public class Scrib_invoke_func extends Pf_func_base {
|
||||||
@Override public int Id() {return Xol_kwd_grp_.Id_invoke;}
|
@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);}
|
@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);
|
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");
|
Thread_adp thread = Thread_adp_.Start_by_key("scribunto", invoker, "default");
|
||||||
while (thread.Thread__is_alive()) {
|
while (thread.Thread__is_alive()) {
|
||||||
|
Thread_adp_.Sleep(10);
|
||||||
if (System_.Ticks__elapsed_in_frac(timeBgn) > timeoutInMs) {
|
if (System_.Ticks__elapsed_in_frac(timeBgn) > timeoutInMs) {
|
||||||
thread.Thread__interrupt();
|
thread.Thread__stop();
|
||||||
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));
|
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)
|
if (invoke_wkr != null)
|
||||||
invoke_wkr.Eval_end(ctx.Page(), mod_name, fnc_name, log_time_bgn);
|
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.mod_raw = mod_raw;
|
||||||
this.fnc_name = fnc_name;
|
this.fnc_name = fnc_name;
|
||||||
}
|
}
|
||||||
|
public Exception Exc;
|
||||||
public Object Invk(GfsCtx gctx, int ikey, String k, GfoMsg m) {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user