Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
StackExchange.Redis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tsai
StackExchange.Redis
Commits
6580a824
Unverified
Commit
6580a824
authored
Aug 29, 2018
by
Marc Gravell
Committed by
GitHub
Aug 29, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
remove indirect vector usage (on < net472, at least); it breaks the world (#932)
parent
83e7d4e7
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
79 additions
and
42 deletions
+79
-42
BufferReader.cs
src/StackExchange.Redis/BufferReader.cs
+2
-3
ConnectionMultiplexer.cs
src/StackExchange.Redis/ConnectionMultiplexer.cs
+0
-30
ExtensionMethods.cs
src/StackExchange.Redis/ExtensionMethods.cs
+47
-0
StackExchange.Redis.csproj
src/StackExchange.Redis/StackExchange.Redis.csproj
+13
-2
Program.cs
toys/TestConsole/Program.cs
+14
-4
TestConsole.csproj
toys/TestConsole/TestConsole.csproj
+3
-3
No files found.
src/StackExchange.Redis/BufferReader.cs
View file @
6580a824
...
@@ -155,7 +155,7 @@ public void Consume(int count)
...
@@ -155,7 +155,7 @@ public void Consume(int count)
if
(
reader
.
RemainingThisSpan
==
0
)
continue
;
if
(
reader
.
RemainingThisSpan
==
0
)
continue
;
var
span
=
reader
.
SlicedSpan
;
var
span
=
reader
.
SlicedSpan
;
int
found
=
span
.
IndexOf
(
value
);
int
found
=
span
.
VectorSafe
IndexOf
(
value
);
if
(
found
>=
0
)
return
totalSkipped
+
found
;
if
(
found
>=
0
)
return
totalSkipped
+
found
;
totalSkipped
+=
span
.
Length
;
totalSkipped
+=
span
.
Length
;
...
@@ -168,7 +168,6 @@ public void Consume(int count)
...
@@ -168,7 +168,6 @@ public void Consume(int count)
int
totalSkipped
=
0
;
int
totalSkipped
=
0
;
bool
haveTrailingCR
=
false
;
bool
haveTrailingCR
=
false
;
ReadOnlySpan
<
byte
>
CRLF
=
stackalloc
byte
[
2
]
{
(
byte
)
'\r'
,
(
byte
)
'\n'
};
do
do
{
{
if
(
reader
.
RemainingThisSpan
==
0
)
continue
;
if
(
reader
.
RemainingThisSpan
==
0
)
continue
;
...
@@ -180,7 +179,7 @@ public void Consume(int count)
...
@@ -180,7 +179,7 @@ public void Consume(int count)
haveTrailingCR
=
false
;
haveTrailingCR
=
false
;
}
}
int
found
=
span
.
IndexOf
(
CRLF
);
int
found
=
span
.
VectorSafeIndexOfCRLF
(
);
if
(
found
>=
0
)
return
totalSkipped
+
found
;
if
(
found
>=
0
)
return
totalSkipped
+
found
;
haveTrailingCR
=
span
[
span
.
Length
-
1
]
==
'\r'
;
haveTrailingCR
=
span
[
span
.
Length
-
1
]
==
'\r'
;
...
...
src/StackExchange.Redis/ConnectionMultiplexer.cs
View file @
6580a824
...
@@ -966,38 +966,8 @@ internal ServerEndPoint GetServerEndPoint(EndPoint endpoint, TextWriter log = nu
...
@@ -966,38 +966,8 @@ internal ServerEndPoint GetServerEndPoint(EndPoint endpoint, TextWriter log = nu
internal
readonly
CommandMap
CommandMap
;
internal
readonly
CommandMap
CommandMap
;
[
MethodImpl
(
MethodImplOptions
.
NoInlining
)]
private
static
void
CheckNumericsVectors
()
{
try
{
CheckNumericsVectorsImpl
();
}
catch
(
Exception
ex
)
{
throw
new
InvalidOperationException
(
"It looks like there's a problem resolving System.Numerics.Vectors.dll; "
+
"this is a well-known pain point between .NET Framework and .NET Core - "
+
"try adding an explicit package reference to System.Numerics.Vectors; "
+
"and if you're wondering 'why do you need that?' - we actually don't: "
+
"it is a down-stream dependency that we don't need directly, but which "
+
"keeps causing pain."
,
ex
);
}
}
[
MethodImpl
(
MethodImplOptions
.
NoInlining
)]
private
static
void
CheckNumericsVectorsImpl
()
{
DoNothingWith
(
System
.
Numerics
.
Vector
.
IsHardwareAccelerated
,
System
.
Numerics
.
Vector
<
byte
>.
Count
);
}
[
MethodImpl
(
MethodImplOptions
.
NoInlining
)]
#pragma warning disable RCS1163 // Unused parameter.
private
static
void
DoNothingWith
(
bool
b
,
int
i
)
{
}
#pragma warning restore RCS1163 // Unused parameter.
private
ConnectionMultiplexer
(
ConfigurationOptions
configuration
)
private
ConnectionMultiplexer
(
ConfigurationOptions
configuration
)
{
{
CheckNumericsVectors
();
IncludeDetailInExceptions
=
true
;
IncludeDetailInExceptions
=
true
;
IncludePerformanceCountersInExceptions
=
false
;
IncludePerformanceCountersInExceptions
=
false
;
...
...
src/StackExchange.Redis/ExtensionMethods.cs
View file @
6580a824
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.IO
;
using
System.Net.Security
;
using
System.Net.Security
;
using
System.Runtime.CompilerServices
;
using
System.Security.Authentication
;
using
System.Security.Authentication
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Text
;
using
System.Text
;
...
@@ -224,5 +225,51 @@ protected override void Dispose(bool disposing)
...
@@ -224,5 +225,51 @@ protected override void Dispose(bool disposing)
if
(
disposing
)
_parent
.
Dispose
();
if
(
disposing
)
_parent
.
Dispose
();
}
}
}
}
// IMPORTANT: System.Numerics.Vectors is just... broken on .NET with anything < net472; the dependency
// indirection routinely fails and causes epic levels of fail. We're going to get around this by simply
// *not using SpanHelpers.IndexOf* (which is what uses it) for net < net472 builds. I've tried every
// trick (including some that are pure evil), and I can't see a better mechanism. Ultimately, the bindings
// fail in unusual and unexpected ways, causing:
//
// Could not load file or assembly 'System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
// or one of its dependencies.The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
//
// also; note that the nuget tools *do not* reliably (or even occasionally) produce the correct
// assembly-binding-redirect entries to fix this up, so; it would present an unreasonable support burden
// otherwise. And yes, I've tried explicitly referencing System.Numerics.Vectors in the manifest to
// force it... nothing. Nada.
#if VECTOR_SAFE
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
internal
static
int
VectorSafeIndexOf
(
this
ReadOnlySpan
<
byte
>
span
,
byte
value
)
=>
span
.
IndexOf
(
value
);
[
MethodImpl
(
MethodImplOptions
.
AggressiveInlining
)]
internal
static
int
VectorSafeIndexOfCRLF
(
this
ReadOnlySpan
<
byte
>
span
)
{
ReadOnlySpan
<
byte
>
CRLF
=
stackalloc
byte
[
2
]
{
(
byte
)
'\r'
,
(
byte
)
'\n'
};
return
span
.
IndexOf
(
CRLF
);
}
#else
internal
static
int
VectorSafeIndexOf
(
this
ReadOnlySpan
<
byte
>
span
,
byte
value
)
{
// yes, this has zero optimization; I'm OK with this as the fallback strategy
for
(
int
i
=
0
;
i
<
span
.
Length
;
i
++)
{
if
(
span
[
i
]
==
value
)
return
i
;
}
return
-
1
;
}
internal
static
int
VectorSafeIndexOfCRLF
(
this
ReadOnlySpan
<
byte
>
span
)
{
// yes, this has zero optimization; I'm OK with this as the fallback strategy
for
(
int
i
=
1
;
i
<
span
.
Length
;
i
++)
{
if
(
span
[
i
]
==
'\n'
&&
span
[
i
-
1
]
==
'\r'
)
return
i
-
1
;
}
return
-
1
;
}
#endif
}
}
}
}
src/StackExchange.Redis/StackExchange.Redis.csproj
View file @
6580a824
...
@@ -12,18 +12,29 @@
...
@@ -12,18 +12,29 @@
<!-- we should preferably not include this in release builds, but isn't dramatic -->
<!-- we should preferably not include this in release builds, but isn't dramatic -->
<DefineConstants>$(DefineConstants);TEST</DefineConstants>
<DefineConstants>$(DefineConstants);TEST</DefineConstants>
<VectorSafe>true</VectorSafe>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net461'">
<VectorSafe>false</VectorSafe>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net472'">
<!--<PackageReference Include="System.IO.Compression" Version="4.3.0" />-->
</PropertyGroup>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug' and '$(Computername)'=='OCHO'">
<PropertyGroup Condition="'$(Configuration)' == 'Debug' and '$(Computername)'=='OCHO'">
<!--<DefineConstants>$(DefineConstants);LOGOUTPUT</DefineConstants>-->
<!--<DefineConstants>$(DefineConstants);LOGOUTPUT</DefineConstants>-->
</PropertyGroup>
</PropertyGroup>
<PropertyGroup Condition="'$(VectorSafe)' == 'true'">
<DefineConstants>$(DefineConstants);VECTOR_SAFE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<ItemGroup>
<PackageReference Include="Pipelines.Sockets.Unofficial" Version="1.0.0" />
<PackageReference Include="Pipelines.Sockets.Unofficial" Version="1.0.0" />
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="4.5.0" />
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="4.5.0" />
<PackageReference Include="System.IO.Pipelines" Version="4.5.0" />
<PackageReference Include="System.IO.Pipelines" Version="4.5.0" />
<PackageReference Include="System.Threading.Channels" Version="4.5.0" />
<PackageReference Include="System.Threading.Channels" Version="4.5.0" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
</ItemGroup>
</ItemGroup>
</Project>
</Project>
\ No newline at end of file
toys/TestConsole/Program.cs
View file @
6580a824
...
@@ -11,15 +11,19 @@ private static async Task Main()
...
@@ -11,15 +11,19 @@ private static async Task Main()
using
(
var
conn
=
Create
())
using
(
var
conn
=
Create
())
{
{
var
sub
=
conn
.
GetSubscriber
();
var
sub
=
conn
.
GetSubscriber
();
Console
.
WriteLine
(
"Subscsribe..."
);
sub
.
Subscribe
(
"foo"
,
(
channel
,
value
)
=>
Console
.
WriteLine
(
$"
{
channel
}
:
{
value
}
"
));
sub
.
Subscribe
(
"foo"
,
(
channel
,
value
)
=>
Console
.
WriteLine
(
$"
{
channel
}
:
{
value
}
"
));
Console
.
WriteLine
(
"Ping..."
);
sub
.
Ping
();
sub
.
Ping
();
Console
.
WriteLine
(
"Run publish..."
);
await
RunPub
().
ConfigureAwait
(
false
);
await
RunPub
().
ConfigureAwait
(
false
);
}
}
await
Console
.
Out
.
WriteLineAsync
(
"Waiting a minute..."
).
ConfigureAwait
(
false
);
await
Console
.
Out
.
WriteLineAsync
(
"Waiting a minute..."
).
ConfigureAwait
(
false
);
await
Task
.
Delay
(
60
*
1000
).
ConfigureAwait
(
false
);
await
Task
.
Delay
(
60
*
1000
).
ConfigureAwait
(
false
);
}
}
private
static
ConnectionMultiplexer
Create
()
private
static
ConnectionMultiplexer
Create
()
{
{
var
options
=
new
ConfigurationOptions
var
options
=
new
ConfigurationOptions
...
@@ -29,12 +33,18 @@ private static ConnectionMultiplexer Create()
...
@@ -29,12 +33,18 @@ private static ConnectionMultiplexer Create()
SyncTimeout
=
int
.
MaxValue
,
SyncTimeout
=
int
.
MaxValue
,
// CommandMap = CommandMap.Create(new HashSet<string> { "subscribe", "psubscsribe", "publish" }, false),
// CommandMap = CommandMap.Create(new HashSet<string> { "subscribe", "psubscsribe", "publish" }, false),
};
};
var
muxer
=
ConnectionMultiplexer
.
Connect
(
options
);
muxer
.
ConnectionFailed
+=
(
s
,
a
)
=>
Console
.
WriteLine
(
$"Failed:
{
a
.
ConnectionType
}
,
{
a
.
EndPoint
}
,
{
a
.
FailureType
}
,
{
a
.
Exception
}
"
);
Console
.
WriteLine
(
"Connecting..."
);
muxer
.
ConnectionRestored
+=
(
s
,
a
)
=>
Console
.
WriteLine
(
$"Restored:
{
a
.
ConnectionType
}
,
{
a
.
EndPoint
}
,
{
a
.
FailureType
}
,
{
a
.
Exception
}
"
);
var
muxer
=
ConnectionMultiplexer
.
Connect
(
options
,
Console
.
Out
);
muxer
.
GetDatabase
().
Ping
();
Console
.
WriteLine
(
"Connected"
);
muxer
.
ConnectionFailed
+=
(
_
,
a
)
=>
Console
.
WriteLine
(
$"Failed:
{
a
.
ConnectionType
}
,
{
a
.
EndPoint
}
,
{
a
.
FailureType
}
,
{
a
.
Exception
}
"
);
muxer
.
ConnectionRestored
+=
(
_
,
a
)
=>
Console
.
WriteLine
(
$"Restored:
{
a
.
ConnectionType
}
,
{
a
.
EndPoint
}
,
{
a
.
FailureType
}
,
{
a
.
Exception
}
"
);
Console
.
WriteLine
(
"Ping..."
);
var
time
=
muxer
.
GetDatabase
().
Ping
();
Console
.
WriteLine
(
$"Pinged:
{
time
.
TotalMilliseconds
}
ms"
);
return
muxer
;
return
muxer
;
}
}
public
static
async
Task
RunPub
()
public
static
async
Task
RunPub
()
{
{
using
(
var
conn
=
Create
())
using
(
var
conn
=
Create
())
...
...
toys/TestConsole/TestConsole.csproj
View file @
6580a824
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
<PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.1;net47</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1;net4
62;net4
7</TargetFrameworks>
<LangVersion>latest</LangVersion>
<LangVersion>latest</LangVersion>
</PropertyGroup>
</PropertyGroup>
...
@@ -11,9 +11,9 @@
...
@@ -11,9 +11,9 @@
</PropertyGroup>
</PropertyGroup>
<ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\tests\BasicTest\BasicTest.csproj" />
<
!--<
ProjectReference Include="..\..\tests\BasicTest\BasicTest.csproj" />
<ProjectReference Include="..\StackExchange.Redis.Server\StackExchange.Redis.Server.csproj" />
<ProjectReference Include="..\StackExchange.Redis.Server\StackExchange.Redis.Server.csproj" />
<ProjectReference Include="..\..\tests\StackExchange.Redis.Tests\StackExchange.Redis.Tests.csproj" />
<ProjectReference Include="..\..\tests\StackExchange.Redis.Tests\StackExchange.Redis.Tests.csproj" />
-->
<ProjectReference Include="..\..\src\StackExchange.Redis\StackExchange.Redis.csproj" />
<ProjectReference Include="..\..\src\StackExchange.Redis\StackExchange.Redis.csproj" />
</ItemGroup>
</ItemGroup>
</Project>
</Project>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment