mercredi 5 septembre 2018

Reset CacheIDFetcher Timer Thread in Birt

I am using birt for report generation , we use jboss as server and when undeploying and deploying the application multiple time , without startup we have some classes renaming in the memory eventually which leads to OOM error . Our investigation shows that CacheIDFetcher starts a timer thread .

 public class CacheIDFetcher
  {
    private static CacheIDFetcher instance = null;
    private static long idleTime = 3600 * 1000;
    private Map<String, Long> activeCacheIDs;

    public static CacheIDFetcher getInstance( )
    {
        if( instance!= null )
            return instance;
        synchronized ( CacheIDFetcher.class )
        {
            if( instance != null )
                return instance;
            instance = new CacheIDFetcher( );
            return instance;
        }
    }

    private CacheIDFetcher ()
    {
        this.activeCacheIDs = new java.util.concurrent.ConcurrentHashMap<String, Long>( );
        Timer timer = new Timer( true );
        TimerTask task = new CacheIDPurgeTimeTask( );
        timer.schedule( task, 0, idleTime );
    }

    public String getCacheID( Map appContext )
    {
        try
        {
            if ( appContext == null )
                return null;
            //Only apply to memory cache
            Object option = appContext.get( DataEngine.MEMORY_DATA_SET_CACHE );
            if( option == null )
                return null;
            Object o = appContext.get( DataEngine.QUERY_EXECUTION_SESSION_ID );
            if ( o != null )
            {
                String cacheID = o.toString( );
                this.activeCacheIDs.put( cacheID, System.currentTimeMillis( ) );
                return cacheID;
            }
        }
        catch ( Exception e )
        {
        }
        return null;
    }

    private class CacheIDPurgeTimeTask extends TimerTask
    {

        @Override
        public void run( )
        {
            //Do not synchronize here.
            Set<String> inActiveCacheIDs = new HashSet<String>();
            long currentTime = System.currentTimeMillis( );
            String[] keyArray = activeCacheIDs.keySet( ).toArray( new String[]{} );

            for( String cacheID : keyArray )
            {
                long lastAccessTime = activeCacheIDs.get( cacheID );
                if( currentTime - lastAccessTime > idleTime )
                {
                    inActiveCacheIDs.add( cacheID );
                }
            }

            CacheMapManager.clearCache( inActiveCacheIDs );
            for( String cacheID: inActiveCacheIDs )
                activeCacheIDs.remove( cacheID );
        }

    }
}

I need to stop this thread after each undeploy is there any way by Reflection in java .





Aucun commentaire:

Enregistrer un commentaire