Skip to content

Commit 3794b4c

Browse files
authored
Merge pull request #1428 from rabbitmq/rabbitmq-dotnet-client-1420
Add cancellation to initial socket connection
2 parents 52f494c + 2aed524 commit 3794b4c

39 files changed

+691
-409
lines changed

.ci/windows/gha-setup.ps1

+67-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
$ProgressPreference = 'Continue'
2+
$VerbosePreference = 'Continue'
23
$ErrorActionPreference = 'Stop'
34
Set-StrictMode -Version 2.0
45

@@ -38,7 +39,7 @@ $erlang_install_dir = Join-Path -Path $HOME -ChildPath 'erlang'
3839

3940
Write-Host '[INFO] Downloading Erlang...'
4041

41-
if (-Not (Test-Path $erlang_installer_path))
42+
if (-Not (Test-Path -LiteralPath $erlang_installer_path))
4243
{
4344
Invoke-WebRequest -UseBasicParsing -Uri $erlang_download_url -OutFile $erlang_installer_path
4445
}
@@ -54,26 +55,76 @@ $rabbitmq_installer_download_url = "https://github.com/rabbitmq/rabbitmq-server/
5455
$rabbitmq_installer_path = Join-Path -Path $base_installers_dir -ChildPath "rabbitmq-server-$rabbitmq_ver.exe"
5556
Write-Host "[INFO] rabbitmq installer path $rabbitmq_installer_path"
5657

57-
$erlang_reg_path = 'HKLM:\SOFTWARE\Ericsson\Erlang'
58-
if (Test-Path 'HKLM:\SOFTWARE\WOW6432Node\')
58+
if (Test-Path -LiteralPath 'HKLM:\SOFTWARE\WOW6432Node\')
5959
{
60-
$erlang_reg_path = 'HKLM:\SOFTWARE\WOW6432Node\Ericsson\Erlang'
60+
New-Variable -Name erlangRegKeyPath -Option Constant `
61+
-Value 'HKLM:\SOFTWARE\WOW6432Node\Ericsson\Erlang'
62+
}
63+
else
64+
{
65+
New-Variable -Name erlangRegKeyPath -Option Constant `
66+
-Value 'HKLM:\SOFTWARE\Ericsson\Erlang'
67+
}
68+
69+
New-Variable -Name erlangRegKey -Option Constant `
70+
-Value (Get-ChildItem $erlangRegKeyPath)
71+
72+
if ($erlangRegKey -eq $null) {
73+
Write-Error "Could not find Erlang installation registry key at $erlangRegKeyPath"
74+
}
75+
76+
New-Variable -Name erlangErtsVersion -Option Constant `
77+
-Value (Select-Object -InputObject $erlangRegKey -Last 1).PSChildName
78+
Write-Verbose "erlangErtsVersion: $erlangErtsVersion"
79+
80+
New-Variable -Name erlangErtsRegKeyPath -Option Constant `
81+
-Value "HKLM:\SOFTWARE\WOW6432Node\Ericsson\Erlang\$erlangErtsVersion"
82+
83+
New-Variable -Name erlangErtsRegKey -Option Constant `
84+
-Value (Get-ItemProperty -LiteralPath HKLM:\SOFTWARE\WOW6432Node\Ericsson\Erlang\$erlangErtsVersion)
85+
86+
if ($erlangErtsRegKey -eq $null) {
87+
Write-Error "Could not find Erlang erts registry key at $erlangErtsRegKeyPath"
88+
}
89+
90+
New-Variable -Name erlangProgramFilesPath -Option Constant `
91+
-Value ($erlangErtsRegKey.'(default)')
92+
93+
if (Test-Path -LiteralPath $erlangProgramFilesPath) {
94+
Write-Verbose "Erlang installation directory: '$erlangProgramFilesPath'"
95+
}
96+
else {
97+
Write-Error 'Could not find Erlang installation directory!'
98+
}
99+
100+
New-Variable -Name allowedExes -Option Constant -Value @('erl.exe', 'epmd.exe', 'werl.exe')
101+
102+
New-Variable -Name exes -Option Constant -Value `
103+
$(Get-ChildItem -Filter '*.exe' -Recurse -LiteralPath $erlangProgramFilesPath | Where-Object { $_.Name -in $allowedExes })
104+
105+
foreach ($exe in $exes) {
106+
$fwRuleName = "rabbitmq-allow-$($exe.Name)-$(Get-Random)"
107+
Write-Verbose "Updating or creating firewall rule for '$exe' - fwRuleName: $fwRuleName"
108+
if (!(Get-NetFirewallRule -ErrorAction 'SilentlyContinue' -Name $fwRuleName)) {
109+
New-NetFirewallRule -Enabled True -Name $fwRuleName -DisplayName $fwRuleName -Direction In -Program $exe -Profile Any -Action Allow
110+
}
111+
else {
112+
Set-NetFirewallRule -Enabled True -Name $fwRuleName -DisplayName $fwRuleName -Direction In -Program $exe -Profile Any -Action Allow
113+
}
61114
}
62-
$erlang_erts_version = Get-ChildItem -Path $erlang_reg_path -Name
63-
$erlang_home = (Get-ItemProperty -LiteralPath $erlang_reg_path\$erlang_erts_version).'(default)'
64115

65-
Write-Host "[INFO] Setting ERLANG_HOME to '$erlang_home'..."
66-
$env:ERLANG_HOME = $erlang_home
67-
[Environment]::SetEnvironmentVariable('ERLANG_HOME', $erlang_home, 'Machine')
68-
Add-Content -Verbose -LiteralPath $env:GITHUB_ENV -Value "ERLANG_HOME=$erlang_home"
116+
Write-Host "[INFO] Setting ERLANG_HOME to '$erlangProgramFilesPath'..."
117+
$env:ERLANG_HOME = $erlangProgramFilesPath
118+
[Environment]::SetEnvironmentVariable('ERLANG_HOME', $erlangProgramFilesPath, 'Machine')
119+
Add-Content -Verbose -LiteralPath $env:GITHUB_ENV -Value "ERLANG_HOME=$erlangProgramFilesPath"
69120

70121
Write-Host "[INFO] Setting RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS..."
71122
$env:RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS = '-rabbitmq_stream advertised_host localhost'
72123
[Environment]::SetEnvironmentVariable('RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS', '-rabbitmq_stream advertised_host localhost', 'Machine')
73124

74125
Write-Host '[INFO] Downloading RabbitMQ...'
75126

76-
if (-Not (Test-Path $rabbitmq_installer_path))
127+
if (-Not (Test-Path -LiteralPath $rabbitmq_installer_path))
77128
{
78129
Invoke-WebRequest -UseBasicParsing -Uri $rabbitmq_installer_download_url -OutFile $rabbitmq_installer_path
79130
}
@@ -83,15 +134,15 @@ else
83134
}
84135

85136
Write-Host "[INFO] Installer dir '$base_installers_dir' contents:"
86-
Get-ChildItem -Verbose -Path $base_installers_dir
137+
Get-ChildItem -Verbose -LiteralPath $base_installers_dir
87138

88139
$rabbitmq_conf_in_file = Join-Path -Path $ci_windows_dir -ChildPath 'rabbitmq.conf.in'
89140
$rabbitmq_appdata_dir = Join-Path -Path $env:AppData -ChildPath 'RabbitMQ'
90141
New-Item -Path $rabbitmq_appdata_dir -ItemType Directory
91142
$rabbitmq_conf_file = Join-Path -Path $rabbitmq_appdata_dir -ChildPath 'rabbitmq.conf'
92143

93144
Write-Host "[INFO] Creating RabbitMQ configuration file in '$rabbitmq_appdata_dir'"
94-
Get-Content $rabbitmq_conf_in_file | %{ $_ -replace '@@CERTS_DIR@@', $certs_dir } | %{ $_ -replace '\\', '/' } | Set-Content -Path $rabbitmq_conf_file
145+
Get-Content $rabbitmq_conf_in_file | %{ $_ -replace '@@CERTS_DIR@@', $certs_dir } | %{ $_ -replace '\\', '/' } | Set-Content -LiteralPath $rabbitmq_conf_file
95146
Get-Content $rabbitmq_conf_file
96147

97148
Write-Host '[INFO] Creating Erlang cookie files...'
@@ -114,9 +165,9 @@ Write-Host '[INFO] Installing and starting RabbitMQ...'
114165
& $rabbitmq_installer_path '/S' | Out-Null
115166
(Get-Service -Name RabbitMQ).Status
116167

117-
$rabbitmq_base_path = (Get-ItemProperty -Name Install_Dir -Path 'HKLM:\SOFTWARE\WOW6432Node\VMware, Inc.\RabbitMQ Server').Install_Dir
168+
$rabbitmq_base_path = (Get-ItemProperty -Name Install_Dir -LiteralPath 'HKLM:\SOFTWARE\WOW6432Node\VMware, Inc.\RabbitMQ Server').Install_Dir
118169
$regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\RabbitMQ'
119-
if (Test-Path 'HKLM:\SOFTWARE\WOW6432Node\')
170+
if (Test-Path -LiteralPath 'HKLM:\SOFTWARE\WOW6432Node\')
120171
{
121172
$regPath = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\RabbitMQ'
122173
}
@@ -138,7 +189,7 @@ $env:RABBITMQ_RABBITMQCTL_PATH = $rabbitmqctl_path
138189
$epmd_running = $false
139190
[int]$count = 1
140191

141-
$epmd_exe = Join-Path -Path $erlang_home -ChildPath "erts-$erlang_erts_version" | Join-Path -ChildPath 'bin' | Join-Path -ChildPath 'epmd.exe'
192+
$epmd_exe = Join-Path -Path $erlangProgramFilesPath -ChildPath "erts-$erlangErtsVersion" | Join-Path -ChildPath 'bin' | Join-Path -ChildPath 'epmd.exe'
142193

143194
Write-Host "[INFO] Waiting for epmd ($epmd_exe) to report that RabbitMQ has started..."
144195

.ci/windows/versions.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"erlang": "26.1.2",
3-
"rabbitmq": "3.12.6"
3+
"rabbitmq": "3.12.10"
44
}

projects/Benchmarks/Benchmarks.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</PropertyGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="BenchmarkDotNet" Version="0.13.9" />
18+
<PackageReference Include="BenchmarkDotNet" Version="0.13.11" />
1919
<PackageReference Include="Ductus.FluentDocker" Version="2.10.59" />
2020
</ItemGroup>
2121

projects/RabbitMQ.Client.OAuth2/RabbitMQ.Client.OAuth2.csproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
</PropertyGroup>
3939

4040
<ItemGroup Condition="'$(Configuration)' == 'Release' and '$(SourceRoot)' == ''">
41-
<SourceRoot Include="$(MSBuildThisFileDirectory)/"/>
41+
<SourceRoot Include="$(MSBuildThisFileDirectory)/" />
4242
</ItemGroup>
4343

4444
<ItemGroup>
@@ -54,10 +54,10 @@
5454
</ItemGroup>
5555

5656
<ItemGroup>
57-
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
57+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
5858
<PackageReference Include="MinVer" Version="4.3.0" PrivateAssets="all" />
59-
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
60-
<PackageReference Include="System.Text.Json" Version="7.0.3" />
59+
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
60+
<PackageReference Include="System.Text.Json" Version="8.0.0" />
6161
</ItemGroup>
6262

6363
<ItemGroup>

projects/RabbitMQ.Client/RabbitMQ.Client.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767

6868
<ItemGroup>
6969
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
70-
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
70+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
7171
<PackageReference Include="MinVer" Version="4.3.0" PrivateAssets="all" />
7272
<PackageReference Include="System.Memory" Version="4.5.5" />
7373
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />

projects/RabbitMQ.Client/client/TaskExtensions.cs

+17
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,23 @@ internal static class TaskExtensions
4040
#if !NET6_0_OR_GREATER
4141
private static readonly TaskContinuationOptions s_tco = TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously;
4242
private static void IgnoreTaskContinuation(Task t, object s) => t.Exception.Handle(e => true);
43+
44+
public static async Task WithCancellation(this Task task, CancellationToken cancellationToken)
45+
{
46+
var tcs = new TaskCompletionSource<bool>();
47+
48+
// https://devblogs.microsoft.com/pfxteam/how-do-i-cancel-non-cancelable-async-operations/
49+
using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
50+
{
51+
if (task != await Task.WhenAny(task, tcs.Task))
52+
{
53+
task.Ignore();
54+
throw new OperationCanceledException(cancellationToken);
55+
}
56+
}
57+
58+
await task.ConfigureAwait(false);
59+
}
4360
#endif
4461

4562
public static Task TimeoutAfter(this Task task, TimeSpan timeout)

projects/RabbitMQ.Client/client/api/ConnectionConfig.cs

+5-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131

3232
using System;
3333
using System.Collections.Generic;
34-
34+
using System.Threading;
35+
using System.Threading.Tasks;
3536
using RabbitMQ.Client.Impl;
3637

3738
namespace RabbitMQ.Client
@@ -142,7 +143,7 @@ public sealed class ConnectionConfig
142143
/// </summary>
143144
public readonly int DispatchConsumerConcurrency;
144145

145-
internal readonly Func<AmqpTcpEndpoint, IFrameHandler> FrameHandlerFactory;
146+
internal readonly Func<AmqpTcpEndpoint, CancellationToken, Task<IFrameHandler>> FrameHandlerFactoryAsync;
146147

147148
internal ConnectionConfig(string virtualHost, string userName, string password,
148149
ICredentialsProvider credentialsProvider, ICredentialsRefresher credentialsRefresher,
@@ -152,7 +153,7 @@ internal ConnectionConfig(string virtualHost, string userName, string password,
152153
TopologyRecoveryFilter topologyRecoveryFilter, TopologyRecoveryExceptionHandler topologyRecoveryExceptionHandler,
153154
TimeSpan networkRecoveryInterval, TimeSpan heartbeatInterval, TimeSpan continuationTimeout, TimeSpan handshakeContinuationTimeout, TimeSpan requestedConnectionTimeout,
154155
bool dispatchConsumersAsync, int dispatchConsumerConcurrency,
155-
Func<AmqpTcpEndpoint, IFrameHandler> frameHandlerFactory)
156+
Func<AmqpTcpEndpoint, CancellationToken, Task<IFrameHandler>> frameHandlerFactoryAsync)
156157
{
157158
VirtualHost = virtualHost;
158159
UserName = userName;
@@ -174,7 +175,7 @@ internal ConnectionConfig(string virtualHost, string userName, string password,
174175
RequestedConnectionTimeout = requestedConnectionTimeout;
175176
DispatchConsumersAsync = dispatchConsumersAsync;
176177
DispatchConsumerConcurrency = dispatchConsumerConcurrency;
177-
FrameHandlerFactory = frameHandlerFactory;
178+
FrameHandlerFactoryAsync = frameHandlerFactoryAsync;
178179
}
179180
}
180181
}

0 commit comments

Comments
 (0)