|
8 | 8 | import java.time.ZoneOffset; |
9 | 9 | import java.time.ZonedDateTime; |
10 | 10 | import java.time.format.DateTimeFormatter; |
11 | | -import java.util.concurrent.RejectedExecutionException; |
12 | 11 | import java.util.concurrent.ScheduledExecutorService; |
13 | 12 | import java.util.concurrent.TimeUnit; |
14 | | -import java.util.concurrent.atomic.AtomicReference; |
15 | 13 |
|
16 | | -import io.jooby.SneakyThrows; |
| 14 | +import io.netty.util.AsciiString; |
17 | 15 |
|
18 | | -public class NettyDateService { |
19 | | - private static final AtomicReference<String> cachedDateString = new AtomicReference<>(); |
20 | | - private static final Runnable INVALIDATE_TASK = () -> cachedDateString.set(null); |
| 16 | +public class NettyDateService implements Runnable { |
21 | 17 | private static final int DATE_INTERVAL = 1000; |
22 | | - private final ScheduledExecutorService scheduler; |
| 18 | + private AsciiString date; |
23 | 19 |
|
24 | 20 | public NettyDateService(ScheduledExecutorService scheduler) { |
25 | | - this.scheduler = scheduler; |
| 21 | + scheduler.scheduleAtFixedRate(this, 0, DATE_INTERVAL, TimeUnit.MILLISECONDS); |
26 | 22 | } |
27 | 23 |
|
28 | | - public String date() { |
29 | | - var dateString = cachedDateString.get(); |
30 | | - if (dateString == null) { |
31 | | - // set the time and register a timer to invalidate it |
32 | | - // note that this is racey, it does not matter if multiple threads do this |
33 | | - // the perf cost of synchronizing would be more than the perf cost of multiple threads running |
34 | | - // it |
35 | | - long realTime = System.currentTimeMillis(); |
36 | | - long mod = realTime % DATE_INTERVAL; |
37 | | - long toGo = DATE_INTERVAL - mod; |
38 | | - dateString = DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC)); |
39 | | - if (cachedDateString.compareAndSet(null, dateString)) { |
40 | | - try { |
41 | | - scheduler.schedule(INVALIDATE_TASK, toGo, TimeUnit.MILLISECONDS); |
42 | | - } catch (RejectedExecutionException rejected) { |
43 | | - if (!scheduler.isShutdown()) { |
44 | | - throw SneakyThrows.propagate(rejected); |
45 | | - } |
46 | | - } |
47 | | - } |
48 | | - } |
49 | | - return dateString; |
| 24 | + public AsciiString date() { |
| 25 | + return this.date; |
| 26 | + } |
| 27 | + |
| 28 | + @Override |
| 29 | + public void run() { |
| 30 | + this.date = |
| 31 | + new AsciiString( |
| 32 | + DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now(ZoneOffset.UTC))); |
50 | 33 | } |
51 | 34 | } |
0 commit comments