All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.thoughtworks.selenium.grid.hub.remotecontrol.RemoteControlProvisioner Maven / Gradle / Ivy

The newest version!
package com.thoughtworks.selenium.grid.hub.remotecontrol;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Central authority to track registered remote controls and grant exclusive
 * access to a remote control for a while.
 * 

* A client will block if it attempts to reserve a remote control and none is * available. The call will return as soon as a remote control becomes available * again. */ public class RemoteControlProvisioner { private static final Log LOGGER = LogFactory.getLog(RemoteControlProvisioner.class); private final List remoteControls; private final Lock remoteControlListLock; private final Condition remoteControlAvailable; public RemoteControlProvisioner() { remoteControls = new LinkedList(); remoteControlListLock = new ReentrantLock(); remoteControlAvailable = remoteControlListLock.newCondition(); } public RemoteControlProxy reserve() { RemoteControlProxy remoteControl; try { remoteControlListLock.lock(); if (remoteControls.isEmpty()) { return null; } remoteControl = blockUntilARemoteControlIsAvailable(); while (remoteControl.unreliable()) { LOGGER.warn("Reserved RC " + remoteControl + " is detected as unreliable, unregistering it and reserving a new one..."); tearDownExistingRemoteControl(remoteControl); if (remoteControls.isEmpty()) { return null; } remoteControl = blockUntilARemoteControlIsAvailable(); } remoteControl.registerNewSession(); LOGGER.info("Reserved remote control" + remoteControl); return remoteControl; } finally { remoteControlListLock.unlock(); } } public void release(RemoteControlProxy remoteControl) { try { remoteControlListLock.lock(); remoteControl.unregisterSession(); LOGGER.info("Released remote control" + remoteControl); signalThatARemoteControlHasBeenMadeAvailable(); } finally { remoteControlListLock.unlock(); } } public void add(RemoteControlProxy newRemoteControl) { try { remoteControlListLock.lock(); if (remoteControls.contains(newRemoteControl)) { tearDownExistingRemoteControl(newRemoteControl); } remoteControls.add(newRemoteControl); signalThatARemoteControlHasBeenMadeAvailable(); } finally { remoteControlListLock.unlock(); } } /** Not Thread-safe */ public boolean contains(RemoteControlProxy remoteControl) { return remoteControls.contains(remoteControl); } public void tearDownExistingRemoteControl(RemoteControlProxy newRemoteControl) { final RemoteControlProxy oldRemoteControl; oldRemoteControl = remoteControls.get(remoteControls.indexOf(newRemoteControl)); remoteControls.remove(oldRemoteControl); } public boolean remove(RemoteControlProxy remoteControl) { try { remoteControlListLock.lock(); return remoteControls.remove(remoteControl); } finally { remoteControlListLock.unlock(); } } /** * Not thread safe. * * @return All available remote controls. Never null. */ public List availableRemoteControls() { final LinkedList availableremoteControls; availableremoteControls = new LinkedList(); for (RemoteControlProxy remoteControl : remoteControls) { if (remoteControl.canHandleNewSession()) { availableremoteControls.add(remoteControl); } } return Arrays.asList(availableremoteControls.toArray(new RemoteControlProxy[availableremoteControls.size()])); } /** * Not thread safe. * * @return All reserved remote controls. Never null. */ public List reservedRemoteControls() { final LinkedList reservedRemoteControls; reservedRemoteControls = new LinkedList(); for (RemoteControlProxy remoteControl : remoteControls) { if (remoteControl.sesssionInProgress()) { reservedRemoteControls.add(remoteControl); } } return Arrays.asList(reservedRemoteControls.toArray(new RemoteControlProxy[reservedRemoteControls.size()])); } protected RemoteControlProxy blockUntilARemoteControlIsAvailable() { RemoteControlProxy availableRemoteControl; while (true) { try { availableRemoteControl = findNextAvailableRemoteControl(); while (null == availableRemoteControl) { LOGGER.info("Waiting for an remote control..."); waitForARemoteControlToBeAvailable(); availableRemoteControl = findNextAvailableRemoteControl(); } return availableRemoteControl; } catch (InterruptedException e) { LOGGER.error("Interrupted while reserving remote control", e); } } } /** * Non-blocking, not thread-safe * * @return Next Available remote control. Null if none is available. */ protected RemoteControlProxy findNextAvailableRemoteControl() { for (RemoteControlProxy remoteControl : remoteControls) { if (remoteControl.canHandleNewSession()) { return remoteControl; } } return null; } protected void waitForARemoteControlToBeAvailable() throws InterruptedException { remoteControlAvailable.await(); } protected void signalThatARemoteControlHasBeenMadeAvailable() { remoteControlAvailable.signalAll(); } public List allRemoteControls() { final LinkedList allRemoteControls; allRemoteControls = new LinkedList(); for (RemoteControlProxy remoteControl : remoteControls) { allRemoteControls.add(remoteControl); } return allRemoteControls; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy