From 608ba2bb5fffbc2b6950fdb3d69f137e1bd80da5 Mon Sep 17 00:00:00 2001
From: Dor Blayzer <59066376+Dor-bl@users.noreply.github.com>
Date: Fri, 12 Jan 2024 10:22:31 +0200
Subject: [PATCH] refactor: Replace obsolete WebRequest,HttpWebRequest with
HttpClient (#720)
* refactor: Replace obsolete WebRequest,HttpWebRequest with HttpClient
* chore: Reuse the same HttpClient instance across multiple requests.
* chore: Review fixes
* chore: Move ConfigureAwait(false) to the calling method
* fix: Revert disposing of SharedHttpClient
* chore: add ConfigureAwait(false) to GetResponse
* refactor: Extract method for shared HttpClient initialization
* chore: Introduce StartAsync to remove the usage of .Result
* chore: Introduce IsRunningAsync method in order to remove the usage of .Result from IsRunning method
* chore: add ConfigureAwait(false) to PingAsync calls
* chore: make SharedHttpClient a field
---
.../Appium/Service/AppiumLocalService.cs | 73 ++++++++++++++-----
1 file changed, 54 insertions(+), 19 deletions(-)
diff --git a/src/Appium.Net/Appium/Service/AppiumLocalService.cs b/src/Appium.Net/Appium/Service/AppiumLocalService.cs
index b66ef2cf..d643a147 100644
--- a/src/Appium.Net/Appium/Service/AppiumLocalService.cs
+++ b/src/Appium.Net/Appium/Service/AppiumLocalService.cs
@@ -20,10 +20,15 @@
using System.IO;
using System.Linq;
using System.Net;
+using System.Net.Http;
using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
namespace OpenQA.Selenium.Appium.Service
{
+ ///
+ /// Represents a local Appium server service that can be started and stopped programmatically.
+ ///
public class AppiumLocalService : ICommandServer
{
private readonly FileInfo NodeJS;
@@ -32,6 +37,7 @@ public class AppiumLocalService : ICommandServer
private readonly int Port;
private readonly TimeSpan InitializationTimeout;
private readonly IDictionary EnvironmentForProcess;
+ private readonly HttpClient SharedHttpClient;
private Process Service;
private List ArgsList;
@@ -55,6 +61,19 @@ internal AppiumLocalService(
Port = port;
InitializationTimeout = initializationTimeout;
EnvironmentForProcess = environmentForProcess;
+ SharedHttpClient = CreateHttpClientInstance;
+ }
+
+ private HttpClient CreateHttpClientInstance
+ {
+ get
+ {
+ SocketsHttpHandler handler = new SocketsHttpHandler
+ {
+ PooledConnectionLifetime = TimeSpan.FromMinutes(2)
+ };
+ return new HttpClient(handler);
+ }
}
///
@@ -68,10 +87,20 @@ internal AppiumLocalService(
public event DataReceivedEventHandler OutputDataReceived;
///
- /// Starts the defined appium server
+ /// Starts the defined Appium server.
+ ///
+ ///
+ /// This method executes the synchronous version of starting the Appium server.
+ ///
+ ///
///
[MethodImpl(MethodImplOptions.Synchronized)]
public void Start()
+ {
+ StartAsync().GetAwaiter().GetResult();
+ }
+
+ private async Task StartAsync()
{
if (IsRunning)
{
@@ -112,7 +141,7 @@ public void Start()
throw new AppiumServerHasNotBeenStartedLocallyException(msgTxt, e);
}
- isLaunched = Ping(InitializationTimeout);
+ isLaunched = await PingAsync(InitializationTimeout).ConfigureAwait(false);
if (!isLaunched)
{
DestroyProcess();
@@ -138,7 +167,9 @@ private void DestroyProcess()
}
finally
{
- Service.Close();
+ Service?.Close();
+
+ SharedHttpClient.Dispose();
}
}
@@ -173,14 +204,19 @@ public bool IsRunning
return false;
}
- return Ping(new TimeSpan(0, 0, 0, 0, 500));
+ return IsRunningAsync(TimeSpan.FromMilliseconds(500)).GetAwaiter().GetResult();
}
}
+ private async Task IsRunningAsync(TimeSpan timeout)
+ {
+ return await PingAsync(timeout).ConfigureAwait(false);
+ }
+
private string GetArgsValue(string argStr)
{
int idx;
- idx= ArgsList.IndexOf(argStr);
+ idx = ArgsList.IndexOf(argStr);
return ArgsList[idx + 1];
}
@@ -199,7 +235,7 @@ private string ParseBasePath()
private void GenerateArgsList()
{
- ArgsList = Arguments.Split(' ').ToList();
+ ArgsList = Arguments.Split(' ').ToList();
}
private Uri CreateStatusUrl()
{
@@ -215,7 +251,7 @@ private Uri CreateStatusUrl()
if (service.IsLoopback || IP.ToString().Equals(AppiumServiceConstants.DefaultLocalIPAddress))
{
- var tmpStatus = "http://localhost:" + Convert.ToString(Port);
+ string tmpStatus = "http://localhost:" + Convert.ToString(Port);
if (defBasePath)
{
status = new Uri(tmpStatus + AppiumServiceConstants.StatusUrl);
@@ -239,7 +275,7 @@ private Uri CreateStatusUrl()
return status;
}
- private bool Ping(TimeSpan span)
+ private async Task PingAsync(TimeSpan span)
{
bool pinged = false;
@@ -250,28 +286,27 @@ private bool Ping(TimeSpan span)
DateTime endTime = DateTime.Now.Add(span);
while (!pinged & DateTime.Now < endTime)
{
- HttpWebRequest request = (HttpWebRequest)WebRequest.Create(status);
- HttpWebResponse response = null;
try
{
- using (response = (HttpWebResponse) request.GetResponse())
+ HttpResponseMessage response = await GetHttpResponseAsync(status).ConfigureAwait(false);
+
+ if (response.IsSuccessStatusCode)
{
- pinged = true;
+ return true;
}
}
catch
{
pinged = false;
}
- finally
- {
- if (response != null)
- {
- response.Close();
- }
- }
}
return pinged;
}
+
+ private async Task GetHttpResponseAsync(Uri status)
+ {
+ HttpResponseMessage response = await SharedHttpClient.GetAsync(status).ConfigureAwait(false);
+ return response;
+ }
}
}
\ No newline at end of file