/* * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.buildServer.clouds.vmware.vmrun.remote.server; import com.intellij.openapi.diagnostic.Logger; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import jetbrains.buildServer.clouds.vmware.vmrun.remote.RemoteTask; import jetbrains.buildServer.clouds.vmware.vmrun.remote.RemoteTaskResult; import jetbrains.buildServer.clouds.vmware.vmrun.remote.VMRunServer; import jetbrains.buildServer.util.ExceptionUtil; import org.jetbrains.annotations.NotNull; /** * @author Eugene Petrenko * Created: 08.12.2009 12:05:12 */ public class Server implements VMRunServer { private static final long TIMEOUT = 20*60; private static final Logger LOG = Logger.getInstance(Server.class.getName()); private final Class myInterface; private final ConcurrentMap> myClients = new ConcurrentHashMap>(); public Server(final Class anInterface, @NotNull final ScheduledExecutorService service) { myInterface = anInterface; if (!anInterface.isInterface()) { throw new IllegalArgumentException(" should be an interface"); } service.scheduleWithFixedDelay(ExceptionUtil.catchAll("VMWare server cleaup clients", new Runnable() { public void run() { try { final long now = new Date().getTime(); final List toRemove = new ArrayList(); for (RemoteClient client : myClients.values()) { if (!client.hasPendingTasks() && client.getLastCommunicationTimestamp().getTime() + TIMEOUT * 1000 < now) { LOG.debug("Client " + client.getId() + " is removed on timeout."); toRemove.add(client.getId()); client.dispose(); } } for (String id : toRemove) { myClients.remove(id); } } catch (Throwable t) { LOG.warn("Failed to cleanup alive clients list"); } } }), TIMEOUT, TIMEOUT, TimeUnit.SECONDS); } @NotNull private RemoteClient findClient(String clientInfo) { RemoteClient cli = new RemoteClient(clientInfo, myInterface); final RemoteClient ret = myClients.putIfAbsent(clientInfo, cli); return ret == null ? cli : ret; } @NotNull public Collection getTasks(@NotNull final String clientInfo) { final RemoteClient cli = findClient(clientInfo); return cli.getPendingTasks(); } public void postResults(@NotNull final String clientInfo, @NotNull final Collection result) { final RemoteClient cli = findClient(clientInfo); cli.acceptTasks(result); } public Collection getAliveClients() { List list = new ArrayList(); for (RemoteClient client : myClients.values()) { if (client.isAlive()) { list.add(client.proxy()); } } return list; } }