Short version: WebElement.submit() is blocking; thus I can't utilize the time page being rendered to do something else.
Long version:
I'm using WebDriver Java Client Library 2.16.1
I have an automated test current done serially but can be done in parallel (basically log in to n different users to check status). Thus I'm trying use Thread to make it run concurrently: fire up multiple instances of Firefox at the same time.
The example code:
public class FirefoxRunnable implements Runnable {
#Override
public void run() {
WebDriver d = new FirefoxDriver();
d.get("http://www.facebook.com");
d.findElement(By.id("email")).sendKeys("username");
d.findElement(By.id("pass")).sendKeys("password");
d.findElement(By.id("pass")).submit();
}
}
public static void test() {
Thread t1 = new Thread(new FirefoxRunnable("Thread 1"));
Thread t2 = new Thread(new FirefoxRunnable("Thread 2"));
t1.start();
t2.start();
}
Problem: d.findElement(By.id("pass")).submit() is blocking while the page is being loaded.
Any suggestion on how to utilize the time page being loaded to do something useful?
You can not actually. Ultimately d.findElement(By.id("pass")).submit() has to be executed by CPU and if its a blocking call then it is going to utilize CPU (I am talking all this in context of single core). However modern OS will give a time slice to each thread so this is not necessary that from start to end all the time will be taken up by d.findElement(By.id("pass")).submit(). CPU will basically give your other threads and parent thread chance to execute.
Rather than submit , you can alternatively simulate Keypress "Keys.ENTER", which wont be blocking, and then you can explicit wait or find_element body tag (or any method that dont block) in ur sleep loop e.g >
for loop{
if not found() //found (e.g findElement(body)) is non blocking, make sure no implicit wait
sleep(3 secs) // while sleep utilize this time
}
Related
I have a JSP application in which a webpage calls five methods one by one (all of them fetch data from different sources) and display charts based on data.
To load the webpage fastly, I planned to call all the five methods in parallel with the help of FixedThreadPool Executor.
Should I shut down my executor once I get the result from all five methods? Shutting down the executor is a bad idea according to me, since if someone opens the webpage a second time it will require the executor to initialize again in order to call the five methods parallelly.
However, I'm not sure about the consequences of leaving the executor open so not sure how to proceed.
Leaving it open is the normal way to use a thread pool. That's the whole point of thread pools: It's to prevent your application from having to create and then destroy however many new threads every time it needs to load a page. Instead, it can just use the same threads again and again.
In chapter 7 of "Java Concurrency in Practice" there is an example just like this, where a so called one-shot execution service is proposed:
If a method needs to process a batch of tasks and does not return until all the
tasks are finished, it can simplify service lifecycle management by using a private
Executor whose lifetime is bounded by that method.
Its code example:
boolean checkMail(Set<String> hosts, long timeout, TimeUnit unit)
throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
final AtomicBoolean hasNewMail = new AtomicBoolean(false);
try {
for (final String host : hosts)
exec.execute(new Runnable() {
public void run() {
if (checkMail(host))
hasNewMail.set(true);
}
});
} finally {
exec.shutdown();
exec.awaitTermination(timeout, unit);
}
return hasNewMail.get();
}
I'd suggest simplifying your code using this approach.
I am trying to use a Third Party Internal Library which is processing a given request. Unfortunately it is synchronous in nature. Also I have no control on the code for the same. Basically it is a function call. This function seems to a bit erratic in behavior. Sometimes this function takes 10 ms to complete processing and sometimes it takes up to 300 secs to process the request.
Can you suggest me a way to write a wrapper around this function so that it would throw an interrupted exception if the function does not complete processing with x ms/secs. I can live with not having the results and continue processing, but cannot tolerate a 3 min delay.
PS: This function internally sends an update to another system using JMS and waits for that system to respond and sends apart from some other calculations.
Can you suggest me a way to write a wrapper around this function so that it would throw an interrupted exception if the function does not complete processing with x ms/secs.
This is not possible. InterruptException only gets thrown by specific methods. You can certainly call thread.stop() but this is deprecated and not recommended for a number of reasons.
A better alternative would be for your code to wait for the response for a certain amount of time and just abandon the call if doesn't work. For example, you could submit a Callable to a thread pool that actually makes the call to the "Third Party Internal Library". Then your main code would do a future.get(...) with a specific timeout.
// allows 5 JMS calls concurrently, change as necessary or used newCachedThreadPool()
ExecutorService threadPool = Executors.newFixedThreadPool(5);
...
// submit the call to be made in the background by thread-pool
Future<Response> future = threadPool.submit(new Callable<Response>() {
public Response call() {
// this damn call can take 3 to 3000ms to complete dammit
return thirdPartyInternalLibrary.makeJmsRequest();
}
});
// wait for some max amount of time
Response response = null;
try {
response = future.get(TimeUnit.MILLISECONDS, 100);
} catch (TimeoutException te) {
// log that it timed out and continue or throw an exception
}
The problem with this method is that you might spawn a whole bunch of threads waiting for the library to respond to the remote JMS query that you would not have a lot of control over.
No easy solution.
This will throw a TimeoutException if the lambda doesn't finish in the time allotted:
CompletableFuture.supplyAsync(() -> yourCall()).get(1, TimeUnit.SECONDS)
Being that this is 3rd party you cannot modify the code. As such you will need to do two things
Launch the execution in a new thread.
Wait for execution in current thread, with timeout.
One possible way would be to use a Semaphore.
final Semaphore semaphore = new Semaphore(0);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// do work
semaphore.release();
}
});
t.start();
try {
semaphore.tryAcquire(1, TimeUnit.SECONDS); // Whatever your timeout is
} catch (InterruptedException e) {
// handle cleanup
}
The above method is gross, I would suggest instead updateing your desing to use a dedicated worker queue or RxJava with a timeout if possible.
I have programmed a structure that works like this:
Activity discoveryActivity - UI thread
↕ Calls through interface
Service discoveryService - Bound service running on UI thread
↕ Actions through Handler.post(↑) or functions (↓)
Runnable connectionThread - Socket networking
At some point the connectionThread needs a String to continue.
So I make a call with Handler.post(..) to the discoveryService which
notifies the discoveryActivity to show an AlertDialog
The user needs about 20 seconds to input the data and will confirm the input.
Problem 1: What will the thread do in the meantime?
Now I need to make my way down to the Thread again.
Getting to discoveryService is easy
Problem 2: How can I get the thread working again without restarting? The thread is in a complex loop with a few Sockets right now!
My first idea was to keep the thread running
// Inside run()
while(stringWrapper.get() == null) {
Thread.sleep(500);
}
// Outside run()
void setStr(String s) { stringWrapper.set(s); }
But that is inefficient
Then I read about wait() and notify()
I tried that on the thread itself and on the StringWrapper (A simple class that holds a reference to a String)
I am helpless right know and I think wait() and notify() are the right way to go?
Can you give me a hint where I should implement these and on which object they would be called?
TL;DR: I want to let a thread pause until it receives data
Not 100% sure what you're trying to accomplish, but you may be able to use a SettableFuture (from Google Guava library) to solve your issue.
private final SettableFuture<String> stringFuture = SettableFuture.create();
// Inside run()
// This will block your thread until stringFuture is set, or until the given timeout has expired.
final String string = stringFuture.get(1, TimeUnit.MINUTES);
// Outside run()
public void setStr(final String s) {
stringFuture.set(s);
}
How can I create a timeout for each command that is running in parallel using java.util.concurrent.ExecutorService?
My code is something like this:
For example in the code below I need obj1 run for maximum 1 min, and obj2 for 2 mins and others 5 mins.
ExecutorService exService;
exService = Executors.newCachedThreadPool();
exService.execute(obj1);
exService.execute(obj2);
exService.execute(obj3);
exService.execute(obj4);
exService.shutdown();
boolean finshed = exService.awaitTermination(5, TimeUnit.MINUTES);
if (finshed) {
//Doing something
}
EDIT:
Unfortunately the class of obj1 - obj4 is scraping some web pages using WebHarvest that uses jakarta HttpClient for reading web pages and HttpClient (And neither WebHarvest itself) doesn't have any feature for timeout on entire page reading and/or scraping job.
This is my time consuming task and I thought about killing ExecutorService thread after a timeout to handle this problem.
In general, there is no reliable way to make a separate thread quit. In particular, there is no reliable way to interrupt and stop your task after a timeout from outside that task. What you need to do is make the tasks themselves responsible for stopping after their time runs out. Depending on what they do, you might be able to abstract this behaviour into a superclass something like:
public abstract class TimeoutRunnable implements Runnable {
private final long timeLimitMillis;
private long startTimeMillis;
public TimeoutRunnable(long timeLimitMillis) {
this.timeLimitMillis = timeLimitMillis;
}
public final void run() {
startTimeMillis = System.currentTimeMillis();
while (System.currentTimeMillis() - startTimeMillis < timeLimitMillis) {
runIteration();
}
}
protected abstract void runIteration();
}
Then in your subclass override, runIteration() and perform a single "step" of the task.
The only reasonably reliable way to kill a task is to run it in a separate process and kill that process if it times out. Using any other approach with a library which does not support timeouts is likely to be error prone at best.
from my point of view I think that such stuff requires some more robust foundations than plain Java standard classes , that 's why I would suggest to use any scheduler infrastructure (Quartz or any other project) which may gives you handles (job identifiers) to kill your time consuming tasks .
You may have something like this :
Main Thread launches the Quartz Scheduler , receive subscriptions from different jobs
saying : Job1,Job 2 and TimeCheckerJob
TimeCheckerJob would be a forever job ,notified to any new job and would check for living time for each any new job... In this job you would have to deal with start time of each job, beware of the OS clocks and don't try to setup too hard constraints (nanoseconds is pure fiction).
HTH
My 2 cents
Jerome
How to kill the thread?
.....
How to restart them again in multi threading?
Since your post is tagged "Java," I have a good idea of what you are saying. Let's say you start a thread by doing:
Thread foo = new Thread(someRunnable);
foo.start();
Now that destroy and friends are deprecated, you need a way to kill the thread. Luckily for you, there has always been the concept of "interrupts." Simply change your runnable so that, on interrupt, it exits. Then call the thread's interrupt method.
foo.interrupt();
If you wrote your Runnable to handle this correctly, it will stop whatever it is doing and terminate.
Thread.stop() kills a thread, but you definitely don't want to do this (see the API documentation for an explanation why). Thread.interrupt() sends an asynchronous notification to a thread, so that it can shut itself gracefully.
For a comprehensive text on Java multithreading, I recommend B. Goetz, Java Concurrency in Practice, Addison-Wesley Professional.
The preferred way for a Thread to die is for the execution of the run method to go to completion:
Thread t = new Thread(new Runnable() {
public void run() {
// Do something...
// Thread will end gracefully here.
}
}
Once a thread gracefully dies in the example above, the Thread cannot be restarted. (Trying to call Thread.start on a thread that has already been started will cause an IllegalThreadStateException.)
In that case, one can make another instance of the thread and call start on that.
Probably a good place to get more information on threading would be Lesson: Concurrency from The Java Tutorials.
i wrap my worker threads up in their own class and use a terminated property to kill the thread proc loop.
sorry i dont have a java version to hand right now but you should get the idea from this
http://pastie.org/880516
using System.Threading;
namespace LoaderDemo
{
class ParserThread
{
private bool m_Terminated;
private AutoResetEvent m_Signal;
private string m_FilePath;
...
public ParserThread(AutoResetEvent signal, string filePath)
{
m_Signal = signal;
m_FilePath = filePath;
Thread thrd = new Thread(this.ThreadProc);
thrd.Start();
}
public bool Terminated {
set { m_Terminated = value; }
}
private Guid Parse(ref string s)
{
//parse the string s and return a populated Guid object
Guid g = new Guid();
// do stuff...
return g;
}
private void ThreadProc()
{
TextReader tr = null;
string line = null;
int lines = 0;
try
{
tr = new StreamReader(m_FilePath);
while ((line = tr.ReadLine()) != null)
{
if (m_Terminated) break;
Guid g = Parse(ref line);
m_GuidList.Add(g);
lines++;
}
m_Signal.Set(); //signal done
}
finally
{
tr.Close();
}
}
}
}
The best way to kill a thread is to set up a flag for the thread to watch. Program the thread to exit when it sees the flag is set to true. There's no way to restart a killed thread.
If you want to start, stop, restart threads at will, maybe using the Java 5 concurrency package would be a good idea. You can have an Executor that will do a bit of work, and when you need that bit of work to be done again, you can just re-schedule it to be done in the executor.
Regarding your first query on killing thread:
You can find more details about topic in below SE questions:
How to properly stop the Thread in Java?
How can I kill a thread? without using stop();
How to start/stop/restart a thread in Java?
Regarding your second query of re-starting thread, it's not possible in java.
You can find below details in documentation page
public void start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
Instead of plain Threads, you can use advanced concurrent API for thread life cycle management. Have a look at this post for ExecutorService details :
How to properly use Java Executor?