001: /*
002: * This file is part of DrFTPD, Distributed FTP Daemon.
003: *
004: * DrFTPD is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * DrFTPD is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with DrFTPD; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018: package org.drftpd.slaveselection.def;
019:
020: import java.io.FileInputStream;
021: import java.io.FileNotFoundException;
022: import java.io.IOException;
023: import java.util.Collection;
024: import java.util.Iterator;
025: import java.util.Properties;
026:
027: import net.sf.drftpd.NoAvailableSlaveException;
028: import net.sf.drftpd.SlaveUnavailableException;
029: import net.sf.drftpd.master.BaseFtpConnection;
030: import net.sf.drftpd.master.config.ConfigInterface;
031: import net.sf.drftpd.mirroring.Job;
032:
033: import org.drftpd.Bytes;
034: import org.drftpd.GlobalContext;
035: import org.drftpd.PropertyHelper;
036: import org.drftpd.master.RemoteSlave;
037: import org.drftpd.remotefile.LinkedRemoteFileInterface;
038: import org.drftpd.slave.SlaveStatus;
039: import org.drftpd.slave.Transfer;
040: import org.drftpd.slaveselection.SlaveSelectionManagerInterface;
041:
042: /**
043: * @author mog
044: * @version $Id: DefaultSlaveSelectionManager.java 874 2004-12-23 17:43:28Z mog $
045: */
046: public class DefaultSlaveSelectionManager implements
047: SlaveSelectionManagerInterface {
048: private GlobalContext _gctx;
049: private long _minfreespace;
050: private int _maxTransfers;
051: private long _maxBandwidth;
052:
053: public DefaultSlaveSelectionManager(GlobalContext gctx)
054: throws FileNotFoundException, IOException {
055: super ();
056: _gctx = gctx;
057: }
058:
059: public void reload() throws FileNotFoundException, IOException {
060: Properties p = new Properties();
061: FileInputStream fis = null;
062: try {
063: fis = new FileInputStream("conf/slaveselection-old.conf");
064: p.load(fis);
065: } finally {
066: if (fis != null) {
067: fis.close();
068: fis = null;
069: }
070: }
071: _minfreespace = Bytes.parseBytes(PropertyHelper.getProperty(p,
072: "minfreespace"));
073:
074: _maxTransfers = Integer.parseInt(PropertyHelper.getProperty(p,
075: "maxTransfers"));
076: _maxBandwidth = Bytes.parseBytes(PropertyHelper.getProperty(p,
077: "maxBandwidth"));
078: }
079:
080: public RemoteSlave getASlave(Collection rslaves, char direction,
081: BaseFtpConnection conn, LinkedRemoteFileInterface file)
082: throws NoAvailableSlaveException {
083: return getASlaveInternal(rslaves, direction);
084: }
085:
086: public RemoteSlave getASlaveForMaster(
087: LinkedRemoteFileInterface file, ConfigInterface cfg)
088: throws NoAvailableSlaveException {
089: return getASlaveInternal(file.getAvailableSlaves(),
090: Transfer.TRANSFER_SENDING_DOWNLOAD);
091: }
092:
093: public RemoteSlave getASlaveForJobDownload(Job job)
094: throws NoAvailableSlaveException {
095: return getASlaveInternal(job.getFile().getAvailableSlaves(),
096: Transfer.TRANSFER_SENDING_DOWNLOAD);
097: }
098:
099: private RemoteSlave getASlaveInternal(Collection slaves,
100: char direction) throws NoAvailableSlaveException {
101: RemoteSlave bestslave;
102: SlaveStatus beststatus;
103:
104: {
105: Iterator i = slaves.iterator();
106: int bestthroughput;
107:
108: while (true) {
109: if (!i.hasNext()) {
110: throw new NoAvailableSlaveException();
111: }
112:
113: bestslave = (RemoteSlave) i.next();
114:
115: try {
116: beststatus = bestslave.getSlaveStatusAvailable();
117:
118: // throws SlaveUnavailableException
119: } catch (SlaveUnavailableException ex) {
120: continue;
121: }
122:
123: bestthroughput = beststatus
124: .getThroughputDirection(direction);
125:
126: break;
127: }
128:
129: while (i.hasNext()) {
130: RemoteSlave slave = (RemoteSlave) i.next();
131: SlaveStatus status;
132:
133: try {
134: status = slave.getSlaveStatusAvailable();
135: } catch (SlaveUnavailableException ex) {
136: continue;
137: }
138:
139: int throughput = status
140: .getThroughputDirection(direction);
141:
142: if ((beststatus.getDiskSpaceAvailable() < _minfreespace)
143: && (beststatus.getDiskSpaceAvailable() < status
144: .getDiskSpaceAvailable())) {
145: // best slave has less space than "freespace.min" &&
146: // best slave has less space available than current slave
147: bestslave = slave;
148: bestthroughput = throughput;
149: beststatus = status;
150:
151: continue;
152: }
153:
154: if (status.getDiskSpaceAvailable() < _minfreespace) {
155: // current slave has less space available than "freespace.min"
156: // above check made sure bestslave has more space than us
157: continue;
158: }
159:
160: if (throughput == bestthroughput) {
161: if (direction == Transfer.TRANSFER_RECEIVING_UPLOAD) {
162: if (bestslave.getLastUploadReceiving() > slave
163: .getLastUploadReceiving()) {
164: bestslave = slave;
165: bestthroughput = throughput;
166: beststatus = status;
167: }
168: } else if (direction == Transfer.TRANSFER_SENDING_DOWNLOAD) {
169: if (bestslave.getLastDownloadSending() > slave
170: .getLastDownloadSending()) {
171: bestslave = slave;
172: bestthroughput = throughput;
173: beststatus = status;
174: }
175: } else if (direction == Transfer.TRANSFER_THROUGHPUT) {
176: if (bestslave.getLastTransfer() > slave
177: .getLastTransfer()) {
178: bestslave = slave;
179: bestthroughput = throughput;
180: beststatus = status;
181: }
182: }
183: }
184:
185: if (throughput < bestthroughput) {
186: bestslave = slave;
187: bestthroughput = throughput;
188: beststatus = status;
189: }
190: }
191: }
192:
193: if (direction == Transfer.TRANSFER_RECEIVING_UPLOAD) {
194: bestslave
195: .setLastUploadReceiving(System.currentTimeMillis());
196: } else if (direction == Transfer.TRANSFER_SENDING_DOWNLOAD) {
197: bestslave
198: .setLastDownloadSending(System.currentTimeMillis());
199: } else {
200: bestslave
201: .setLastUploadReceiving(System.currentTimeMillis());
202: bestslave
203: .setLastDownloadSending(System.currentTimeMillis());
204: }
205:
206: return bestslave;
207: }
208:
209: public RemoteSlave getASlaveForJobUpload(Job job,
210: RemoteSlave sourceSlave) throws NoAvailableSlaveException {
211: Collection<RemoteSlave> slaves = job.getDestinationSlaves();
212: slaves.removeAll(job.getFile().getAvailableSlaves());
213:
214: return getASlaveForJob(slaves,
215: Transfer.TRANSFER_RECEIVING_UPLOAD);
216: }
217:
218: public RemoteSlave getASlaveForJob(Collection slaves, char direction)
219: throws NoAvailableSlaveException {
220: RemoteSlave rslave = this .getASlaveInternal(slaves, direction);
221: SlaveStatus status = null;
222:
223: try {
224: status = rslave.getSlaveStatusAvailable();
225: } catch (SlaveUnavailableException e) {
226: throw new NoAvailableSlaveException();
227: }
228:
229: if (status.getThroughputDirection(direction) > _maxBandwidth) {
230: throw new NoAvailableSlaveException();
231: }
232:
233: if (direction == Transfer.TRANSFER_RECEIVING_UPLOAD) {
234: if (status.getTransfersReceiving() > _maxTransfers) {
235: throw new NoAvailableSlaveException();
236: }
237: }
238:
239: if (direction == Transfer.TRANSFER_SENDING_DOWNLOAD) {
240: if (status.getTransfersSending() > _maxTransfers) {
241: throw new NoAvailableSlaveException();
242: }
243: }
244:
245: return rslave;
246: }
247:
248: public GlobalContext getGlobalContext() {
249: return _gctx;
250: }
251:
252: }
|