双轨并行任务时死亡情况的webdriver(Track dead WebDriver instanc

2019-07-29 04:17发布

我看到正在运行使用硒webdriver的,简单的例子是,比如并行嵌套循环网络压力测试的一些死亡实例的怪事,创下每100次展示300个独特的网页。

我“成功”获得4 - 8 webdriver的情况下使用会ThreadLocal<FirefoxWebDriver>对他们每个任务线程隔离和MaxDegreeOfParallelism在ParallelOptions实例来限制线程。 我的分区和并行外环只(页面的集合),并检查.IsValueCreatedThreadLocal<>每个分区的“长期运行的任务”的方法开始内部容器。 为了便于以后清理,我每一个新的实例添加到由线程ID键控ConcurrentDictionary。

不管我用什么并列化或分区策略,webdriver的情况下,偶尔会做下列之一:

  • 启动,但永远不会显示一个URL或运行印象
  • 启动,运行任意数量的印象很好,然后就闲置在某些点

当其中任一发生,并行循环,最终似乎注意到一个线程没有做任何事情,并产生一个新的分区。 如果n是允许的线程的数目,这导致在具有n个生产线仅约50-60%的时间。

清理仍然工作在最后罚款; 也可以是2N打开的浏览器或以上,但生产性和非生产性的人都得到清理。

有没有一种方法来监视这些无用的webdriver实例和)清除它们向右走,加上B)得到的并行循环立即更换,而不是落后了好几分钟,因为它现在经常做的任务段,?

Answer 1:

由于没有OnReady事件也不是IsReady财产,我的工作围绕它通过创建每个实例后睡觉线程几秒钟。 这样做似乎给我100%坚固耐用,功能的webdriver实例。

感谢您的建议 ,我已经实现IsReady在我的开源项目功能Webinator 。 使用,如果你想,或者使用下面列出的代码。

我试图实例25分的情况下,和所有的人是有功能的,所以我在这一点上我的算法非常有信心,(我的杠杆作用HtmlAgilityPack,看是否存在的元素,但在这里我要跳过它为简单起见):

public void WaitForReady(IWebDriver driver)
{
    var js = @"{ var temp=document.createElement('div'); temp.id='browserReady';" +
             @"b=document.getElementsByTagName('body')[0]; b.appendChild(temp); }";
    ((IJavaScriptExecutor)driver).ExecuteScript(js);

    WaitForSuccess(() =>
    {
        IWebElement element = null;
        try
        {
            element = driver.FindElement(By.Id("browserReady"));
        }
        catch
        {
            // element not found
        }

        return element != null;
    },
    timeoutInMilliseconds: 10000);

    js = @"{var temp=document.getElementById('browserReady');" +
         @" temp.parentNode.removeChild(temp);}";
    ((IJavaScriptExecutor)driver).ExecuteScript(js);
}

private bool WaitForSuccess(Func<bool> action, int timeoutInMilliseconds)
{
    if (action == null) return false;

    bool success;
    const int PollRate = 250;
    var maxTries = timeoutInMilliseconds / PollRate;
    int tries = 0;
    do
    {
        success = action();
        tries++;
        if (!success && tries <= maxTries)
        {
            Thread.Sleep(PollRate);
        }
    }
    while (!success && tries < maxTries);
    return success;
}

假设是,如果浏览器响应的JavaScript函数,并寻找元素,那么它可能是一个可靠的实例,并随时可以使用。



Answer 2:

我有一个类似的问题。 事实证明,webdriver的没有寻找开放端口的最好方法。 如上所述这里沾到端口的系统范围的锁,找到开放的端口,然后启动实例。 这可以饿死,你试图启动端口的其他实例。

我解决此得到了通过直接在代表用于指定随机端口号ThreadLocal<IWebDriver>是这样的:

        var ports = new List<int>();
        var rand = new Random((int)DateTime.Now.Ticks & 0x0000FFFF);

        var driver = new ThreadLocal<IWebDriver>(() =>
        {
            var profile = new FirefoxProfile();
            var port = rand.Next(50) + 7050;
            while(ports.Contains(port) && ports.Count != 50) port = rand.Next(50) + 7050;
            profile.Port = port;
            ports.Add(port);
            return new FirefoxDriver(profile);
        });

这个工程相当一致的我,但如果你最终是没有解决使用列表中所有50个有问题。



文章来源: Track dead WebDriver instances during parallel task