2008-07-07 02:40:45 +02:00
// ResourceObserver.java
// -----------------------
2010-02-06 19:48:06 +01:00
// (c) David Wieditz; lotus at mail.berlios.de
// first published 6.2.2010
//
// based on the former code (c) by Detlef Reichl; detlef!reichl()gmx!org
2008-07-07 02:40:45 +02:00
// Pforzheim, Germany, 2008
//
2010-02-06 19:48:06 +01:00
// part of YaCy
2008-10-31 12:33:17 +01:00
//
2008-07-07 02:40:45 +02:00
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-07-07 02:03:37 +02:00
package de.anomic.crawler ;
2008-06-06 15:10:21 +02:00
2010-02-06 19:48:06 +01:00
import java.io.File ;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Method ;
2008-06-06 15:10:21 +02:00
2009-10-10 01:13:30 +02:00
import net.yacy.kelondro.logging.Log ;
2009-11-06 20:13:30 +01:00
import net.yacy.kelondro.util.MemoryControl ;
2009-07-19 22:37:44 +02:00
import de.anomic.search.Switchboard ;
import de.anomic.search.SwitchboardConstants ;
2008-06-06 15:10:21 +02:00
2010-02-06 19:48:06 +01:00
public class ResourceObserver {
public static final Log log = new Log ( " RESOURCE OBSERVER " ) ;
2008-10-31 12:33:17 +01:00
// return values for available disk/memory
private static final int LOW = 0 ;
private static final int MEDIUM = 1 ;
private static final int HIGH = 2 ;
2010-02-06 19:48:06 +01:00
private final Switchboard sb ;
private final File path ; // path to check
private int normalizedDiskFree = HIGH ;
private int normalizedMemoryFree = HIGH ;
2008-06-06 15:10:21 +02:00
2010-02-06 19:48:06 +01:00
public ResourceObserver ( final Switchboard sb ) {
2008-06-06 15:10:21 +02:00
this . sb = sb ;
2010-02-06 19:48:06 +01:00
this . path = sb . getConfigPath ( SwitchboardConstants . INDEX_PRIMARY_PATH , " " ) ;
2009-05-21 10:30:34 +02:00
}
public static void initThread ( ) {
2010-02-06 19:48:06 +01:00
final Switchboard sb = Switchboard . getSwitchboard ( ) ;
sb . observer = new ResourceObserver ( Switchboard . getSwitchboard ( ) ) ;
2009-05-21 10:30:34 +02:00
sb . observer . resourceObserverJob ( ) ;
2010-02-06 19:48:06 +01:00
}
2008-11-01 09:56:58 +01:00
/ * *
* checks the resources and pauses crawls if necessary
* /
2008-06-19 14:40:44 +02:00
public void resourceObserverJob ( ) {
2010-01-10 20:04:43 +01:00
MemoryControl . setDHTkbytes ( getMinFreeMemory ( ) ) ;
2010-02-06 19:48:06 +01:00
normalizedDiskFree = getNormalizedDiskFree ( ) ;
normalizedMemoryFree = getNormalizedMemoryFree ( ) ;
if ( normalizedDiskFree < HIGH | | normalizedMemoryFree < HIGH ) {
if ( normalizedDiskFree < HIGH ) { // pause crawls
if ( ! sb . crawlJobIsPaused ( SwitchboardConstants . CRAWLJOB_LOCAL_CRAWL ) ) {
log . logInfo ( " pausing local crawls " ) ;
sb . pauseCrawlJob ( SwitchboardConstants . CRAWLJOB_LOCAL_CRAWL ) ;
}
if ( ! sb . crawlJobIsPaused ( SwitchboardConstants . CRAWLJOB_REMOTE_TRIGGERED_CRAWL ) ) {
log . logInfo ( " pausing remote triggered crawls " ) ;
sb . pauseCrawlJob ( SwitchboardConstants . CRAWLJOB_REMOTE_TRIGGERED_CRAWL ) ;
}
}
if ( ( normalizedDiskFree = = LOW | | normalizedMemoryFree < HIGH ) & & sb . getConfigBool ( SwitchboardConstants . INDEX_RECEIVE_ALLOW , false ) ) {
log . logInfo ( " disabling index receive " ) ;
sb . setConfig ( SwitchboardConstants . INDEX_RECEIVE_ALLOW , false ) ;
sb . peers . mySeed ( ) . setFlagAcceptRemoteIndex ( false ) ;
2010-02-09 18:14:16 +01:00
sb . setConfig ( SwitchboardConstants . INDEX_RECEIVE_AUTODISABLED , true ) ;
2010-02-06 19:48:06 +01:00
}
}
else {
2010-02-09 18:14:16 +01:00
if ( sb . getConfigBool ( SwitchboardConstants . INDEX_RECEIVE_AUTODISABLED , false ) ) { // we were wrong!
2010-02-06 19:48:06 +01:00
log . logInfo ( " enabling index receive " ) ;
sb . setConfig ( SwitchboardConstants . INDEX_RECEIVE_ALLOW , true ) ;
sb . peers . mySeed ( ) . setFlagAcceptRemoteIndex ( true ) ;
2010-02-09 18:14:16 +01:00
sb . setConfig ( SwitchboardConstants . INDEX_RECEIVE_AUTODISABLED , false ) ;
2010-02-06 19:48:06 +01:00
}
log . logInfo ( " resources ok " ) ;
}
}
/ * *
* returns the amount of disk space available
* @return < ul >
* < li > < code > HIGH < / code > if disk space is available < / li >
* < li > < code > MEDIUM < / code > if low disk space is available < / li >
* < li > < code > LOW < / code > if lower than hardlimit disk space is available < / li >
* < / ul >
* /
private int getNormalizedDiskFree ( ) {
final long currentSpace = getUsableSpace ( this . path ) ;
if ( currentSpace < 1L ) return HIGH ;
int ret = HIGH ;
2009-11-06 20:13:30 +01:00
2010-02-06 19:48:06 +01:00
if ( currentSpace < getMinFreeDiskSpace ( ) ) {
log . logWarning ( " Volume " + this . path . toString ( ) + " : free space ( " + ( currentSpace / 1024 / 1024 ) + " MB) is too low (< " + ( getMinFreeDiskSpace ( ) / 1024 / 1024 ) + " MB) " ) ;
ret = MEDIUM ;
}
if ( currentSpace < getMinFreeDiskSpace_hardlimit ( ) ) {
ret = LOW ;
}
return ret ;
}
private int getNormalizedMemoryFree ( ) {
if ( ! MemoryControl . getDHTallowed ( ) ) return LOW ;
return HIGH ;
2008-06-06 15:10:21 +02:00
}
2008-11-01 09:56:58 +01:00
/ * *
* @return < code > true < / code > if disk space is available
* /
2010-02-06 19:48:06 +01:00
public boolean getDiskAvailable ( ) {
return normalizedDiskFree = = HIGH ;
2008-06-06 15:10:21 +02:00
}
2008-11-01 09:56:58 +01:00
/ * *
* @return < code > true < / code > if memory is available
* /
2010-02-06 19:48:06 +01:00
public boolean getMemoryAvailable ( ) {
return normalizedMemoryFree = = HIGH ;
2008-06-06 15:10:21 +02:00
}
2008-06-19 14:40:44 +02:00
/ * *
2010-01-10 20:04:43 +01:00
* @return amount of space ( bytes ) that should be kept free
2008-06-19 14:40:44 +02:00
* /
2010-02-06 19:48:06 +01:00
public long getMinFreeDiskSpace ( ) {
2009-10-31 20:12:53 +01:00
return sb . getConfigLong ( SwitchboardConstants . DISK_FREE , 3000 ) /* MiB */ * 1024L * 1024L ;
}
/ * *
2010-01-10 20:04:43 +01:00
* @return amount of space ( bytes ) that should at least be kept free
2009-10-31 20:12:53 +01:00
* /
2010-02-06 19:48:06 +01:00
public long getMinFreeDiskSpace_hardlimit ( ) {
2009-10-31 20:12:53 +01:00
return sb . getConfigLong ( SwitchboardConstants . DISK_FREE_HARDLIMIT , 100 ) /* MiB */ * 1024L * 1024L ;
2008-06-06 15:10:21 +02:00
}
2010-01-10 20:04:43 +01:00
/ * *
* @return amount of space ( KiB ) that should at least be free
* /
public long getMinFreeMemory ( ) {
return sb . getConfigLong ( SwitchboardConstants . MEMORY_ACCEPTDHT , 0 ) ;
}
2008-06-06 15:10:21 +02:00
2010-02-06 19:48:06 +01:00
/ * *
* This method calls File . getUsableSpace ( ) from Java 6 .
* @param file the path to be checked
* @return " The number of available bytes on the partition or 0L if the abstract pathname does not name a partition. " - 1L on error .
* @author lotus at mail . berlios . de
* /
public static long getUsableSpace ( final File file ) {
try {
final Class < ? > File6 = Class . forName ( " java.io.File " ) ;
final Class < ? > [ ] param = { File . class , String . class } ;
final Constructor < ? > File6Constructor = File6 . getConstructor ( param ) ;
final Object file6 = File6Constructor . newInstance ( file , " " ) ;
final Method getFreeSpace = file6 . getClass ( ) . getMethod ( " getUsableSpace " , ( Class [ ] ) null ) ;
final Object space = getFreeSpace . invoke ( file6 , ( Object [ ] ) null ) ;
return Long . parseLong ( space . toString ( ) ) ;
} catch ( Throwable e ) {
return - 1L ;
}
}
}