summaryrefslogtreecommitdiff
path: root/source/de/anomic/server/serverAbstractThread.java
diff options
context:
space:
mode:
Diffstat (limited to 'source/de/anomic/server/serverAbstractThread.java')
-rw-r--r--source/de/anomic/server/serverAbstractThread.java227
1 files changed, 227 insertions, 0 deletions
diff --git a/source/de/anomic/server/serverAbstractThread.java b/source/de/anomic/server/serverAbstractThread.java
new file mode 100644
index 000000000..88d45e3e0
--- /dev/null
+++ b/source/de/anomic/server/serverAbstractThread.java
@@ -0,0 +1,227 @@
+// serverAbstractThread.java
+// -----------------------
+// (C) by Michael Peter Christen; mc@anomic.de
+// first published on http://www.yacy.net
+// Frankfurt, Germany, 2005
+// last major change: 14.03.2005
+//
+// 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
+//
+// Using this software in any meaning (reading, learning, copying, compiling,
+// running) means that you agree that the Author(s) is (are) not responsible
+// for cost, loss of data or any harm that may be caused directly or indirectly
+// by usage of this softare or this documentation. The usage of this software
+// is on your own risk. The installation and usage (starting/running) of this
+// software may allow other people or application to access your computer and
+// any attached devices and is highly dependent on the configuration of the
+// software which must be done by the user of the software; the author(s) is
+// (are) also not responsible for proper configuration and usage of the
+// software, even if provoked by documentation provided together with
+// the software.
+//
+// Any changes to this file according to the GPL as documented in the file
+// gpl.txt aside this file in the shipment you received can be done to the
+// lines that follows this copyright notice here, but changes must not be
+// done inside the copyright notive above. A re-distribution must contain
+// the intact and unchanged copyright notice.
+// Contributions and changes to the program code must be marked as such.
+
+/*
+ an Implementation of a serverRunnable must only extend this class and impement
+ the methods:
+ open(),
+ job() and
+ close()
+ */
+
+package de.anomic.server;
+
+public abstract class serverAbstractThread extends Thread implements serverThread {
+
+ private long startup = 0, idlePause = 0, busyPause = 0, blockPause = 0;
+ private boolean running = true;
+ private serverLog log = null;
+ private long idletime = 0, busytime = 0;
+ private String shortDescr = "", longDescr = "";
+ private long threadBlockTimestamp = System.currentTimeMillis();
+ private long idleCycles = 0, busyCycles = 0;
+
+ protected void announceThreadBlockApply() {
+ // shall only be used, if a thread blocks for an important reason
+ // like a socket connect and must renew the timestamp to correct
+ // statistics
+ this.threadBlockTimestamp = System.currentTimeMillis();
+ }
+
+ protected void announceThreadBlockRelease() {
+ // shall only be used, if a thread blocks for an important reason
+ // like a socket connect and must renew the timestamp to correct
+ // statistics
+ long thisBlockTime = (System.currentTimeMillis() - this.threadBlockTimestamp);
+ this.blockPause += thisBlockTime;
+ this.busytime -= thisBlockTime;
+ }
+
+ protected void announceMoreExecTime(long millis) {
+ this.busytime += millis;
+ }
+
+ protected void announceMoreSleepTime(long millis) {
+ this.idletime += millis;
+ }
+
+ public void setDescription(String shortText, String longText) {
+ // sets a visible description string
+ this.shortDescr = shortText;
+ this.longDescr = longText;
+ }
+
+ public void setStartupSleep(long milliseconds) {
+ // sets a sleep time before execution of the job-loop
+ startup = milliseconds;
+ }
+
+ public void setIdleSleep(long milliseconds) {
+ // sets a sleep time for pauses between two jobs
+ idlePause = milliseconds;
+ }
+
+ public void setBusySleep(long milliseconds) {
+ // sets a sleep time for pauses between two jobs
+ busyPause = milliseconds;
+ }
+
+ public String getShortDescription() {
+ return this.shortDescr;
+ }
+
+ public String getLongDescription() {
+ return this.longDescr;
+ }
+
+ public long getIdleCycles() {
+ // returns the total number of cycles of job execution with idle-result
+ return this.idleCycles;
+ }
+
+ public long getBusyCycles() {
+ // returns the total number of cycles of job execution with busy-result
+ return this.busyCycles;
+ }
+
+ public long getBlockTime() {
+ // returns the total time that this thread has been blocked so far
+ return this.blockPause;
+ }
+
+ public long getSleepTime() {
+ // returns the total time that this thread has slept so far
+ return this.idletime;
+ }
+
+ public long getExecTime() {
+ // returns the total time that this thread has worked so far
+ return this.busytime;
+ }
+
+ public void setLog(serverLog log) {
+ // defines a log where process states can be written to
+ this.log = log;
+ }
+
+ public void terminate(boolean waitFor) {
+ // after calling this method, the thread shall terminate
+ this.running = false;
+ // wait for termination
+ if (waitFor) while (this.isAlive())
+ try {this.sleep(100);} catch (InterruptedException e) {break;}
+ // If we reach this point, the process is closed
+ }
+
+ private void logError(String text) {
+ if (log == null)
+ serverLog.logError("THREAD-CONTROL", text);
+ else
+ log.logError(text);
+ }
+ private void logSystem(String text) {
+ if (log == null)
+ serverLog.logSystem("THREAD-CONTROL", text);
+ else
+ log.logSystem(text);
+ }
+
+ public void jobExceptionHandler(Exception e) {
+ // default handler for job exceptions. shall be overridden for own handler
+ logError("thread '" + this.getName() + "': " + e.toString());
+ e.printStackTrace();
+ }
+
+ public void run() {
+ if (startup > 0) {
+ // do a startup-delay
+ logSystem("thread '" + this.getName() + "' deployed, delaying start-up.");
+ ratz(startup);
+ if (!(running)) return;
+ }
+ this.open();
+ if (log != null) {
+ if (startup > 0)
+ logSystem("thread '" + this.getName() + "' delayed, " + ((this.busyPause < 0) ? "starting now job." : "starting now loop."));
+ else
+ logSystem("thread '" + this.getName() + "' deployed, " + ((this.busyPause < 0) ? "starting job." : "starting loop."));
+ }
+ int outerloop;
+ long innerpause;
+ long timestamp;
+ boolean isBusy;
+ while (running) {
+ try {
+ // do job
+ timestamp = System.currentTimeMillis();
+ isBusy = this.job();
+ busytime += System.currentTimeMillis() - timestamp;
+ // interrupt loop if this is supposed to be a one-time job
+ if ((this.idlePause < 0) || (this.busyPause < 0)) break; // for one-time jobs
+ // process scheduled pause
+ timestamp = System.currentTimeMillis();
+ ratz((isBusy) ? this.busyPause : this.idlePause);
+ idletime += System.currentTimeMillis() - timestamp;
+ if (isBusy) busyCycles++; else idleCycles++;
+ } catch (Exception e) {
+ // handle exceptions: thread must not die on any unexpected exceptions
+ // if the exception is too bad it should call terminate()
+ this.jobExceptionHandler(e);
+ busyCycles++;
+ }
+ }
+ this.close();
+ logSystem("thread '" + this.getName() + "' terminated.");
+ }
+
+ private void ratz(long millis) {
+ int loop = 1;
+ while (millis > 1000) {
+ loop = loop * 2;
+ millis = millis / 2;
+ }
+ while ((loop-- > 0) && (running)) {
+ try {this.sleep(millis);} catch (InterruptedException e) {}
+ }
+ }
+
+ public void open() {} // dummy definition; should be overriden
+ public void close() {} // dummy definition; should be overriden
+} \ No newline at end of file