SemaphoreLock.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */
  20. package org.openspcoop2.utils;

  21. import java.util.concurrent.Executors;
  22. import java.util.concurrent.ScheduledExecutorService;
  23. import java.util.concurrent.ScheduledFuture;
  24. import java.util.concurrent.TimeUnit;

  25. /**
  26.  * SemaphoreLock
  27.  *
  28.  *
  29.  * @author Poli Andrea (apoli@link.it)
  30.  * @author $Author$
  31.  * @version $Rev$, $Date$
  32.  */
  33. public class SemaphoreLock {

  34.     private static ScheduledExecutorService scheduler = null;
  35.     public static void initScheduledExecutorService() {
  36.         scheduler = Executors.newScheduledThreadPool(1);
  37.     }
  38.     public static boolean isInitializedScheduledExecutorService() {
  39.         return scheduler!=null;
  40.     }
  41.     public static void releaseScheduledExecutorService() {
  42.         if(scheduler!=null) {
  43.             scheduler.shutdown();
  44.         }
  45.     }
  46.    
  47.     private Semaphore semaphore;
  48.     private boolean released = false;
  49.    
  50.     private ScheduledFuture<?> future;
  51.        
  52.     public SemaphoreLock(Semaphore semaphore, String methodName, String idTransazione) {
  53.         this.semaphore = semaphore;
  54.         if(scheduler!=null && this.semaphore.getInstanceLockHoldTimeoutMs()>0) {
  55.             initScheduler(this.semaphore.getInstanceLockHoldTimeoutMs(), this.semaphore.isInstanceDebug(), methodName, idTransazione);
  56.         }
  57.     }
  58.    
  59.     private void initScheduler(long ms, boolean debug, String methodName, String idTransazione) {
  60.         final String logPrefix = " schedule lock hold timeout("+ms+"ms) ";
  61.         if(debug) {
  62.             this.semaphore.debug(this.semaphore.getPrefix(methodName, idTransazione)+logPrefix+"...");
  63.         }
  64.         this.future = scheduler.schedule(() -> {
  65.             if(!this.released) {
  66.                 logReleaseLockStart(debug, methodName, idTransazione, logPrefix);
  67.                 this.semaphore.release(null, methodName, idTransazione);
  68.                 this.released=true;
  69.                 logReleaseLockEnd(debug, methodName, idTransazione, logPrefix);
  70.             }
  71.         }, ms, TimeUnit.MILLISECONDS);
  72.     }
  73.     private void logReleaseLockStart(boolean debug, String methodName, String idTransazione, String logPrefix) {
  74.         String msg = this.semaphore.getPrefix(methodName, idTransazione)+logPrefix+"expired; release lock ...";
  75.         // in caso di wake lo registro comunque poichè non dovrebbe succedere
  76.         if(Semaphore.getLogDebug()!=null) {
  77.             Semaphore.getLogDebug().error(msg);
  78.         }
  79.         if(debug) {
  80.             this.semaphore.debug(msg);
  81.         }
  82.     }
  83.     private void logReleaseLockEnd(boolean debug, String methodName, String idTransazione, String logPrefix) {
  84.         String msg = this.semaphore.getPrefix(methodName, idTransazione)+logPrefix+"expired; lock released";
  85.         if(Semaphore.getLogDebug()!=null) {
  86.             Semaphore.getLogDebug().error(msg);
  87.         }
  88.         if(debug) {
  89.             this.semaphore.debug(msg);
  90.         }
  91.     }
  92.    
  93.     public void release(String methodName, String idTransazione) {
  94.         if(methodName!=null && idTransazione!=null) {
  95.             // nop
  96.         }
  97.         if(!this.released && scheduler!=null) {
  98.             this.future.cancel(false); // Cancella il task, se non è ancora stato eseguito
  99.             this.released = true;
  100.         }
  101.        
  102.     }
  103.    
  104. }