package com.tesora.dve.worker;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.tesora.dve.server.connectionmanager.log.ShutdownLog;
import com.tesora.dve.worker.agent.Agent;
import io.netty.channel.EventLoopGroup;
import org.apache.log4j.Logger;
import com.tesora.dve.common.RemoteException;
import com.tesora.dve.common.catalog.StorageGroup;
import com.tesora.dve.common.catalog.StorageSite;
import com.tesora.dve.comms.client.messages.GenericResponse;
import com.tesora.dve.comms.client.messages.ResponseMessage;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.worker.agent.Envelope;
import com.tesora.dve.server.messaging.WorkerManagerRequest;
public class WorkerManager extends Agent {
Logger logger = Logger.getLogger(WorkerManager.class);
Set<Worker> activeWorkers = new HashSet<Worker>();
public WorkerManager() throws PEException {
super(WorkerManager.class.getSimpleName());
}
@Override
public void onMessage(Envelope e) throws PEException {
Object payload = e.getPayload();
if (payload instanceof WorkerManagerRequest) {
WorkerManagerRequest m = (WorkerManagerRequest)payload;
ResponseMessage resp;
try {
resp = m.executeRequest(e, this);
} catch (Exception ex) {
resp = new GenericResponse().setException(new RemoteException(getName(), ex));
}
if (resp != null)
returnResponse(e, resp);
} else {
throw new PEException("WorkerManager received message of invalid type (" + payload.toString() + ")");
}
}
public Worker getWorker(UserAuthentication auth, AdditionalConnectionInfo additionalConnInfo, StorageSite site, EventLoopGroup preferredEventLoop) throws PEException {
Worker theWorker = site.createWorker(auth, additionalConnInfo, preferredEventLoop);
activeWorkers.add(theWorker);
return theWorker;
}
private void returnWorker(Worker w) throws PEException {
activeWorkers.remove(w);
w.close();
}
public void returnWorkerList(StorageGroup group, Collection<Worker> theWorkers) throws PEException {
ArrayList<StorageSite> groupSites = new ArrayList<StorageSite>();
for (Worker worker : theWorkers) {
groupSites.add(worker.getWorkerSite());
returnWorker(worker);
}
group.returnWorkerSites(this, groupSites);
}
public boolean allWorkersReturned() throws PEException {
boolean allWorkersReturned = (activeWorkers.size() == 0);
for (Worker w : activeWorkers)
logger.error("active worker: " + w);
return allWorkersReturned;
}
private void quiesceWorkerManager() throws PEException {
sendAndReceive(newEnvelope(new WorkerManagerSync()).to(getAddress()));
}
public void shutdown() {
try {
quiesceWorkerManager();
super.close();
activeWorkers.clear();
} catch (PEException e) {
ShutdownLog.logShutdownError("Error shutting down " + getClass().getSimpleName(), e);
}
}
public Map<StorageSite, Worker> getWorkerMap(UserAuthentication auth,
AdditionalConnectionInfo additionalConnInfo, EventLoopGroup preferredEventLoop, Collection<? extends StorageSite> storageSites) throws PEException {
Map<StorageSite, Worker> workerMap = new HashMap<StorageSite, Worker>();
for (StorageSite site : storageSites) {
workerMap.put(site, getWorker(auth, additionalConnInfo, site, preferredEventLoop));
}
return workerMap;
}
}