Mercurial Hosting > luan
comparison src/luan/modules/ThreadLuan.java @ 1766:8df0b80e715e
fix scheduled tasks
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 06 Jun 2023 14:33:24 -0600 |
parents | 7c7f28c724e8 |
children | d3ea0380dfb6 |
comparison
equal
deleted
inserted
replaced
1765:1ffe1e06ea55 | 1766:8df0b80e715e |
---|---|
1 package luan.modules; | 1 package luan.modules; |
2 | 2 |
3 import java.io.Closeable; | 3 import java.io.Closeable; |
4 import java.util.Arrays; | |
5 import java.util.Iterator; | 4 import java.util.Iterator; |
6 import java.util.Map; | 5 import java.util.Map; |
7 import java.util.HashMap; | 6 import java.util.HashMap; |
8 import java.util.concurrent.Executor; | 7 import java.util.concurrent.Executor; |
9 import java.util.concurrent.Executors; | 8 import java.util.concurrent.Executors; |
24 | 23 |
25 | 24 |
26 public final class ThreadLuan { | 25 public final class ThreadLuan { |
27 private static final Logger logger = LoggerFactory.getLogger(ThreadLuan.class); | 26 private static final Logger logger = LoggerFactory.getLogger(ThreadLuan.class); |
28 | 27 |
28 public static final String CLOSEABLES = "Luan.closeables"; | |
29 public interface Closeables { | |
30 public void addCloseable(Closeable c) throws LuanException; | |
31 } | |
32 | |
29 private static final Executor exec = Executors.newCachedThreadPool(); | 33 private static final Executor exec = Executors.newCachedThreadPool(); |
30 public static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); | 34 public static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); |
31 | 35 |
32 private static Runnable runnable(final Luan luan,final LuanFunction fn) { | 36 private static Runnable runnable(final Luan luan,final LuanFunction fn) { |
33 return new Runnable() { | 37 return new Runnable() { |
48 luan = new Luan(luan); | 52 luan = new Luan(luan); |
49 LuanMutable.makeImmutable(fn); | 53 LuanMutable.makeImmutable(fn); |
50 exec.execute(runnable(luan,fn)); | 54 exec.execute(runnable(luan,fn)); |
51 } | 55 } |
52 | 56 |
53 private static final Map<String,ScheduledFuture> scheduleds = new WeakCacheMap<String,ScheduledFuture>(); | |
54 | |
55 private static void cancel(ScheduledFuture sf,String src) { | 57 private static void cancel(ScheduledFuture sf,String src) { |
56 boolean b = sf.cancel(false); | 58 boolean b = sf.cancel(false); |
57 if( !sf.isCancelled() ) | 59 if( !sf.isCancelled() ) |
58 logger.error(src+" cancel="+b+" isCancelled="+sf.isCancelled()+" isDone="+sf.isDone()+" "+sf); | 60 logger.error(src+" cancel="+b+" isCancelled="+sf.isCancelled()+" isDone="+sf.isDone()+" "+sf); |
59 } | 61 } |
80 { | 82 { |
81 options = new LuanTable(options); | 83 options = new LuanTable(options); |
82 Number delay = Utils.removeNumber(options,"delay"); | 84 Number delay = Utils.removeNumber(options,"delay"); |
83 Number repeatingDelay = Utils.removeNumber(options,"repeating_delay"); | 85 Number repeatingDelay = Utils.removeNumber(options,"repeating_delay"); |
84 Number repeatingRate = Utils.removeNumber(options,"repeating_rate"); | 86 Number repeatingRate = Utils.removeNumber(options,"repeating_rate"); |
85 Boolean dontGc = Utils.removeBoolean(options,"dont_gc"); | |
86 String id = Utils.removeString(options,"id"); | 87 String id = Utils.removeString(options,"id"); |
88 if( id != null ) | |
89 logger.error("thread option 'id' is obsolete: "+id); | |
87 if( repeatingDelay!=null && repeatingRate!=null ) | 90 if( repeatingDelay!=null && repeatingRate!=null ) |
88 throw new LuanException("can't define both repeating_delay and repeating_rate"); | 91 throw new LuanException("can't define both repeating_delay and repeating_rate"); |
89 boolean repeating = repeatingDelay!=null || repeatingRate!=null; | 92 boolean repeating = repeatingDelay!=null || repeatingRate!=null; |
90 Utils.checkEmpty(options); | 93 Utils.checkEmpty(options); |
91 if( id != null ) { | |
92 ScheduledFuture sf = scheduleds.remove(id); | |
93 if( sf != null ) | |
94 cancel(sf,"id "+id); | |
95 } | |
96 final Runnable r = runnable(newLuan,fn); | 94 final Runnable r = runnable(newLuan,fn); |
97 final ScheduledFuture sf; | 95 final ScheduledFuture sf; |
98 if( repeatingDelay != null ) { | 96 if( repeatingDelay != null ) { |
99 if( delay==null ) | 97 if( delay==null ) |
100 delay = repeatingDelay; | 98 delay = repeatingDelay; |
107 sf = scheduler.schedule(r,delay.longValue(),TimeUnit.MILLISECONDS); | 105 sf = scheduler.schedule(r,delay.longValue(),TimeUnit.MILLISECONDS); |
108 } else { | 106 } else { |
109 scheduler.schedule(r,0L,TimeUnit.MILLISECONDS); | 107 scheduler.schedule(r,0L,TimeUnit.MILLISECONDS); |
110 return; | 108 return; |
111 } | 109 } |
112 if( !Boolean.TRUE.equals(dontGc) ) { | 110 Closeables cs = (Closeables)luan.registry().get(CLOSEABLES); |
113 Object c = new Object() { | 111 if( cs != null ) { |
112 Closeable cl = new Closeable() { | |
113 public void close() { | |
114 cancel(sf,"close"); | |
115 } | |
114 protected void finalize() throws Throwable { | 116 protected void finalize() throws Throwable { |
115 cancel(sf,"gc"); | 117 cancel(sf,"gc"); // cancel on gc |
116 } | 118 } |
117 }; | 119 }; |
118 luan.registry().put(c,c); // cancel on gc | 120 cs.addCloseable(cl); |
119 } | 121 } |
120 if( id != null ) | |
121 scheduleds.put(id,sf); | |
122 } | 122 } |
123 | 123 |
124 | 124 |
125 public static void sleep(long millis) throws InterruptedException { | 125 public static void sleep(long millis) throws InterruptedException { |
126 Thread.sleep(millis); | 126 Thread.sleep(millis); |