4

I'm trying to setup a producers/consumers using the selenium webdriver as queries/browsers.

While running the following code, not all the queries are actually entered even though the output says they are. Some queries also either get doubled ( i.e. "Fish" becomes "FisFishh" ).

APP

public class App {

    public static void main(String[] args) {

        DriverHashMap.init();

        Executor exec = new Executor();

        // Add queries to list
        Query query = new Query(exec);
        query.addQuery("Cats");
        query.addQuery("Dogs");
        query.addQuery("Fish");
        // query.addQuery("Bats");
        // query.addQuery("Rats");
        // query.addQuery("Geese");

        ExecutorService threadPool = Executors.newFixedThreadPool(4);

        // Submit queries to pool
        Future queryStatus = threadPool.submit(query);

        // Start browsers
        threadPool.execute(new Browser("1", exec));
        threadPool.execute(new Browser("2", exec));

        // this will wait for the producer to finish its execution.
        try {
            queryStatus.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        // Wait for pool to finish
        threadPool.shutdown();

    }
}

BROWSER

public class Browser implements Runnable {
    private String name;
    private Executor exec;

    private static WebDriver driver;
    private static String baseURL = "http://www.google.com";
    private static String query;

    public Browser(String name, Executor exec) {

        synchronized (this) {
            this.name = name;
            this.exec = exec;

            System.out.println("\tStart Browser-" + this.name);
            driver = new FirefoxDriver();
            // Wait up to 30 seconds for a response
            driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

            DriverHashMap.addDriver(name, driver);
            System.out.println("\tAdded Browser-" + name + " to hashmap");
        }

    }

    private void enterQuery() {

        synchronized (this) {
            // Get driver for this browser
            driver = DriverHashMap.getDriver(this.name);
            System.out.println("Browser " + this.name
                    + " entering query from executor: " + query);

            // Search field qbqfq
            driver.findElement(By.id("gbqfq")).clear();

            // Enter query
            driver.findElement(By.id("gbqfq")).sendKeys(query);

            // Click search button
            driver.findElement(By.id("gbqfb")).click();
        }

    }

    public void run() {
        try {

            synchronized (this) {
                // Receive first query
                driver = DriverHashMap.getDriver(this.name);
                query = exec.get();
                System.out.println("Browser " + this.name
                        + "\n\rReceived first query from executor: " + query);
            }

            do {

                synchronized (this) {
                    // Process query
                    driver = DriverHashMap.getDriver(this.name);
                    driver.get(baseURL);
                    enterQuery();
                }

                synchronized (this) {
                    // Receive next query
                    query = exec.get();
                    driver = DriverHashMap.getDriver(this.name);
                    System.out.println("Browser " + this.name
                            + "\n\rReceived new query from executor: " + query);
                }

            } while (query != null);

            // Close this browser
            synchronized (this) {
                driver = DriverHashMap.getDriver(this.name);
                System.out.println("Browser " + this.name
                        + " finished its job; terminating.");

                driver.close();
            }

        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

}

QUERY

public class Query implements Runnable {
    private Executor exec;
    private List<String> queries = new ArrayList<String>();

    public Query(Executor exec) {
        this.exec = exec;
    }

    public void addQuery( String query ) {
        System.out.println("Adding " + query + " to queries");
        queries.add( query );
    }

    public void run() {

        Iterator it = queries.iterator();
        String currQuery = new String();

        try {
            while( it.hasNext()) {
                currQuery = (String)it.next();
                System.out.println("Adding " + currQuery + " to Executor");
                exec.put(currQuery);
            }

            this.exec.continueProducing = Boolean.FALSE;
            System.out.println("Query has finished its job; terminating.");
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

    }
}

EXECUTOR

public class Executor {
    public ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(
            100);
    public Boolean continueProducing = Boolean.TRUE;

    public void put(String query) throws InterruptedException {
        this.queue.put(query);
    }

    public String get() throws InterruptedException {
        return this.queue.poll(1, TimeUnit.SECONDS);
    }
}

1 Answer 1

3

Webdriver is not threadsafe per se. Try wrapping it into a ThreadLocal.

That has helped me a lot in a similar situation.

Sign up to request clarification or add additional context in comments.

1 Comment

I've never heard of ThreadLocal, thank you for the link, i will look into some examples.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.