Mercurial Hosting > luan
changeset 1366:ae2321a09723
improve Thread.schedule
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 17 Jun 2019 21:50:40 -0600 |
parents | 6617763dfd76 |
children | 836e00bf7ce2 |
files | conv.txt src/luan/modules/Thread.luan src/luan/modules/ThreadLuan.java src/luan/modules/host/Hosting.luan |
diffstat | 4 files changed, 87 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
diff -r 6617763dfd76 -r ae2321a09723 conv.txt --- a/conv.txt Wed Jun 12 22:16:10 2019 -0600 +++ b/conv.txt Mon Jun 17 21:50:40 2019 -0600 @@ -1,3 +1,5 @@ +Thread.schedule + java() luan.webserver
diff -r 6617763dfd76 -r ae2321a09723 src/luan/modules/Thread.luan --- a/src/luan/modules/Thread.luan Wed Jun 12 22:16:10 2019 -0600 +++ b/src/luan/modules/Thread.luan Mon Jun 17 21:50:40 2019 -0600 @@ -29,9 +29,10 @@ ThreadLuan.fork(fn) end -function Thread.schedule(delay,fn,repeating) +function Thread.schedule(fn,options) fn = safe(fn) - ThreadLuan.schedule(delay,fn,repeating) + options = options or {} + ThreadLuan.schedule(fn,options) end @@ -80,4 +81,13 @@ return tbl end + +local backup_lock = ThreadLuan.backupLock.readLock() +local run_in_lock = ThreadLuan.runInLock + +function Thread.run_for_backup(fn) + return run_in_lock(backup_lock,fn) +end + + return Thread
diff -r 6617763dfd76 -r ae2321a09723 src/luan/modules/ThreadLuan.java --- a/src/luan/modules/ThreadLuan.java Wed Jun 12 22:16:10 2019 -0600 +++ b/src/luan/modules/ThreadLuan.java Mon Jun 17 21:50:40 2019 -0600 @@ -8,9 +8,13 @@ import java.util.LinkedHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; import luan.Luan; import luan.LuanFunction; import luan.LuanTable; @@ -21,59 +25,74 @@ public final class ThreadLuan { private static final Executor exec = Executors.newCachedThreadPool(); - public static final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1); + public static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - public static void fork(LuanFunction fn) { - LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); - final LuanFunction newFn = (LuanFunction)cloner.get(fn); - exec.execute(new Runnable(){public void run() { - try { - newFn.call(); - } catch(LuanException e) { - e.printStackTrace(); - } - }}); - } -/* - public static LuanFunction synchronized_(final Luan luan,final LuanFunction fn) throws LuanException { - Utils.checkNotNull(fn); - return new LuanFunction() { - @Override public Object call(Luan ingored,Object[] args) throws LuanException { - synchronized(luan) { - return fn.call(luan,args); + private static Runnable runnable(final LuanFunction fn) { + return new Runnable() { + public synchronized void run() { + try { + fn.call(); + } catch(LuanException e) { + e.printStackTrace(); } } }; } -*/ - public static void schedule(long delay,LuanFunction fn,String repeating) + + public static void fork(LuanFunction fn) { + LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); + final LuanFunction newFn = (LuanFunction)cloner.get(fn); + exec.execute(runnable(newFn)); + } + + public static void schedule(LuanFunction fn,LuanTable options) throws LuanException { + Map map = options.asMap(); + Number delay = (Number)map.remove("delay"); + Number repeatingDelay = (Number)map.remove("repeating_delay"); + Number repeatingRate = (Number)map.remove("repeating_rate"); + boolean daemon = Boolean.TRUE.equals(map.remove("daemon")); + final boolean runOnClose = Boolean.TRUE.equals(map.remove("run_on_close")); + if( repeatingDelay!=null && repeatingRate!=null ) + throw new LuanException("can't define both repeating_delay and repeating_rate"); + boolean repeating = repeatingDelay!=null || repeatingRate!=null; + if( !map.isEmpty() ) + throw new LuanException( "unrecognized options: "+map ); Luan luan = fn.luan(); LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); final Luan newLuan = (Luan)cloner.clone(luan); final LuanFunction newFn = (LuanFunction)cloner.get(fn); - Runnable r = new Runnable(){public void run() { - try { - newFn.call(); - } catch(LuanException e) { - e.printStackTrace(); - } - }}; + final Runnable r = runnable(newFn); final ScheduledFuture sf; - if( repeating==null ) { - sf = scheduler.schedule(r,delay,TimeUnit.MILLISECONDS); - } else if( repeating.equals("with_fixed_delay") ) { - sf = scheduler.scheduleWithFixedDelay(r,delay,delay,TimeUnit.MILLISECONDS); - } else if( repeating.equals("at_fixed_rate") ) { - sf = scheduler.scheduleAtFixedRate(r,delay,delay,TimeUnit.MILLISECONDS); + if( repeatingDelay != null ) { + if( delay==null ) + delay = repeatingDelay; + sf = scheduler.scheduleWithFixedDelay(r,delay.longValue(),repeatingDelay.longValue(),TimeUnit.MILLISECONDS); + } else if( repeatingRate != null ) { + if( delay==null ) + delay = repeatingRate; + sf = scheduler.scheduleWithFixedDelay(r,delay.longValue(),repeatingRate.longValue(),TimeUnit.MILLISECONDS); + } else if( delay != null ) { + sf = scheduler.schedule(r,delay.longValue(),TimeUnit.MILLISECONDS); + } else if( runOnClose ) { + Closeable c = new Closeable(){public void close(){ + scheduler.schedule(r,0L,TimeUnit.MILLISECONDS); + }}; + luan.registry().put(c,c); // prevent gc + luan.onClose(c); + return; } else { - throw new LuanException("repeating must be nil or 'with_fixed_delay' or 'at_fixed_rate'"); + scheduler.schedule(r,0L,TimeUnit.MILLISECONDS); + return; } - final Closeable c = new Closeable(){public void close(){ + Closeable c = new Closeable(){public void close(){ boolean b = sf.cancel(false); + if( runOnClose ) + scheduler.schedule(r,0L,TimeUnit.MILLISECONDS); }}; - newLuan.registry().put(luan,luan); // prevent gc + if( !daemon ) + newLuan.registry().put(luan,luan); // prevent gc luan.registry().put(c,c); // prevent gc luan.onClose(c); } @@ -216,4 +235,19 @@ callableMap.remove(name); } + + public static final ReadWriteLock backupLock = new ReentrantReadWriteLock(); + + public static Object runInLock(Lock lock,LuanFunction fn) + throws LuanException, InterruptedException + { + if( !lock.tryLock(10,TimeUnit.MINUTES) ) + throw new LuanException("failed to acquire lock"); + try { + return fn.call(); + } finally { + lock.unlock(); + } + } + }
diff -r 6617763dfd76 -r ae2321a09723 src/luan/modules/host/Hosting.luan --- a/src/luan/modules/host/Hosting.luan Wed Jun 12 22:16:10 2019 -0600 +++ b/src/luan/modules/host/Hosting.luan Mon Jun 17 21:50:40 2019 -0600 @@ -47,7 +47,7 @@ end end for _, there_child in pairs(there.children) do - if host.delete_unused(domain,password,there_child.path)==true then -- remove ==true later + if host.delete_unused(domain,password,there_child.path) then print("deleted "..there_child.name) end end