1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 module hunt.shiro.session.mgt.ExecutorServiceSessionValidationScheduler; 20 21 import hunt.shiro.session.mgt.DefaultSessionManager; 22 import hunt.shiro.session.mgt.SessionValidationScheduler; 23 import hunt.shiro.session.mgt.ValidatingSessionManager; 24 25 import hunt.concurrency.atomic; 26 import hunt.concurrency.thread; 27 28 import hunt.concurrency.Executors; 29 import hunt.concurrency.ScheduledExecutorService; 30 import hunt.concurrency.ThreadFactory; 31 import hunt.util.DateTime; 32 import hunt.util.Common; 33 import hunt.util.Runnable; 34 35 import hunt.logging.Logger; 36 37 import core.thread; 38 import std.conv; 39 40 /** 41 * SessionValidationScheduler implementation that uses a 42 * {@link ScheduledExecutorService} to call {@link ValidatingSessionManager#validateSessions()} every 43 * <em>{@link #getInterval interval}</em> milliseconds. 44 * 45 */ 46 class ExecutorServiceSessionValidationScheduler : SessionValidationScheduler, Runnable { 47 48 /** Private internal log instance. */ 49 50 51 ValidatingSessionManager sessionManager; 52 private ScheduledExecutorService service; 53 private long interval = DefaultSessionManager.DEFAULT_SESSION_VALIDATION_INTERVAL; 54 private bool enabled = false; 55 private string threadNamePrefix = "SessionValidationThread-"; 56 57 this() { 58 } 59 60 this(ValidatingSessionManager sessionManager) { 61 this.sessionManager = sessionManager; 62 } 63 64 ValidatingSessionManager getSessionManager() { 65 return sessionManager; 66 } 67 68 void setSessionManager(ValidatingSessionManager sessionManager) { 69 this.sessionManager = sessionManager; 70 } 71 72 long getInterval() { 73 return interval; 74 } 75 76 void setInterval(long interval) { 77 this.interval = interval; 78 } 79 80 bool isEnabled() { 81 return this.enabled; 82 } 83 84 void setThreadNamePrefix(string threadNamePrefix) { 85 this.threadNamePrefix = threadNamePrefix; 86 } 87 88 string getThreadNamePrefix() { 89 return this.threadNamePrefix; 90 } 91 92 /** 93 * Creates a single thread {@link ScheduledExecutorService} to validate sessions at fixed intervals 94 * and enables this scheduler. The executor is created as a daemon thread to allow JVM to shut down 95 */ 96 //TODO Implement an integration test to test for jvm exit as part of the standalone example 97 // (so we don't have to change the unit test execution model for the core module) 98 void enableSessionValidation() { 99 if (this.interval > 0) { 100 this.service = Executors.newSingleThreadScheduledExecutor(new class ThreadFactory { 101 private shared int count = 0; 102 103 ThreadEx newThread(Runnable r) { 104 int c = AtomicHelper.increment(count); 105 ThreadEx thread = new ThreadEx(r); 106 thread.isDaemon = true; 107 thread.name = threadNamePrefix ~ c.to!string(); 108 return thread; 109 } 110 }); 111 112 Duration dur = interval.msecs; 113 this.service.scheduleAtFixedRate(this, dur, dur); 114 } 115 this.enabled = true; 116 } 117 118 void run() { 119 version(HUNT_DEBUG) { 120 tracef("Executing session validation..."); 121 } 122 long startTime = DateTime.currentTimeMillis(); 123 this.sessionManager.validateSessions(); 124 long stopTime = DateTime.currentTimeMillis(); 125 version(HUNT_DEBUG) { 126 tracef("Session validation completed successfully in " 127 ~ to!string(stopTime - startTime) ~ " milliseconds."); 128 } 129 } 130 131 void disableSessionValidation() { 132 if (this.service !is null) { 133 this.service.shutdownNow(); 134 } 135 this.enabled = false; 136 } 137 }