diff --git a/.github/actions/install/action.yml b/.github/actions/install/action.yml
index 16a73c323..614811d95 100644
--- a/.github/actions/install/action.yml
+++ b/.github/actions/install/action.yml
@@ -59,7 +59,7 @@ runs:
- name: Install .NET #on Windows
- #if: inputs.dotnet == 'true' && inputs.os == 'windows-latest'
+ if: inputs.dotnet == 'true' # && inputs.os == 'windows-latest'
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml
index 9ac1f4699..681585ade 100644
--- a/.github/workflows/build-release.yml
+++ b/.github/workflows/build-release.yml
@@ -285,15 +285,7 @@ jobs:
needs: [ analyze, build-release ]
if: needs.analyze.outputs.todo == 'release'
- steps:
-
- # Install our environment
- - name: Install environment
- uses: ./.github/actions/install
- with:
- os: ubuntu-latest
- dotnet: true
- java: false
+ steps:
# checkout the hazelcast/hazelcast-csharp-client repository
- name: Checkout code
diff --git a/.github/workflows/trigger-release.yml b/.github/workflows/trigger-release.yml
index 4ef447ca7..d0fb8ff9f 100644
--- a/.github/workflows/trigger-release.yml
+++ b/.github/workflows/trigger-release.yml
@@ -56,6 +56,11 @@ jobs:
# finalize + trigger the release
- name: Trigger Release
if: ${{ github.event.inputs.dryrun == 'false' }}
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_OWNER: hazelcast
+ GH_REPO: hazelcast-csharp-client
+ GH_BRANCH: release/${{ github.ref_name }}
shell: pwsh
run: |
./hz.ps1 -noRestore -localRestore update-doc-version
diff --git a/doc/latest-version b/doc/latest-version
index 1e20ec35c..4cc0e35cb 100644
--- a/doc/latest-version
+++ b/doc/latest-version
@@ -1 +1 @@
-5.4.0
\ No newline at end of file
+5.6.0
\ No newline at end of file
diff --git a/doc/versions.md b/doc/versions.md
index 85c2d6871..f118930cc 100644
--- a/doc/versions.md
+++ b/doc/versions.md
@@ -6,7 +6,7 @@ Versions lifecycle and support period follows the Hazelcast [Version Support Win
### Current Version
-* 5.5.0 [general documentation](xref:doc-index-5-4-0) and [API reference](xref:api-index-5-4-0)
+* 5.6.0 [general documentation](xref:doc-index-5-6-0) and [API reference](xref:api-index-5-6-0)
### Preview
diff --git a/doc/xrefmap.yml b/doc/xrefmap.yml
index 6fa3a8881..e77fa4809 100644
--- a/doc/xrefmap.yml
+++ b/doc/xrefmap.yml
@@ -88,3 +88,8 @@ references:
href: 5.4.0/doc/index.html
- uid: api-index-5-4-0
href: 5.4.0/api/index.html
+- uid: doc-index-5-6-0
+ name: 5.6.0
+ href: 5.6.0/doc/index.html
+- uid: api-index-5-6-0
+ href: 5.6.0/api/index.html
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index cc1e7da32..5dd94b394 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -83,9 +83,9 @@
4.0.0-alpha.2
-->
- 5.5.0
- 5.5.0
- 5.5.0
+ 5.6.0
+ 5.6.0
+ 5.6.0
diff --git a/src/Hazelcast.Net.Examples/Hazelcast.Net.Examples.csproj b/src/Hazelcast.Net.Examples/Hazelcast.Net.Examples.csproj
index 9634dd525..de03dfd2d 100644
--- a/src/Hazelcast.Net.Examples/Hazelcast.Net.Examples.csproj
+++ b/src/Hazelcast.Net.Examples/Hazelcast.Net.Examples.csproj
@@ -8,6 +8,11 @@
net8.0;net9.0;net10.0
+
+
+ $(NoWarn);CS1591
+
+
Exe
Hazelcast.Examples
@@ -35,21 +40,4 @@
-
-
-
-
-
-
-
-
-
- SystemLinqAsyncEnumerable
-
-
-
-
-
diff --git a/src/Hazelcast.Net.Linq.Async/Hazelcast.Net.Linq.Async.csproj b/src/Hazelcast.Net.Linq.Async/Hazelcast.Net.Linq.Async.csproj
index a520abe9a..4b0d1e856 100644
--- a/src/Hazelcast.Net.Linq.Async/Hazelcast.Net.Linq.Async.csproj
+++ b/src/Hazelcast.Net.Linq.Async/Hazelcast.Net.Linq.Async.csproj
@@ -51,13 +51,10 @@
-
-
-
+
+
-
+
-
-
+
diff --git a/src/Hazelcast.Net.Testing/Hazelcast.Net.Testing.csproj b/src/Hazelcast.Net.Testing/Hazelcast.Net.Testing.csproj
index 6e16de9b5..aa2400546 100644
--- a/src/Hazelcast.Net.Testing/Hazelcast.Net.Testing.csproj
+++ b/src/Hazelcast.Net.Testing/Hazelcast.Net.Testing.csproj
@@ -1,7 +1,7 @@
- netstandard2.0;netstandard2.1
+ netstandard2.0;netstandard2.1;
@@ -33,10 +33,21 @@
-
-
+
+
+
+
+
+
+
+
+ MicrosoftBclMemory
+
+
+
+
diff --git a/src/Hazelcast.Net.Testing/TestData/EmployeeTestObject.cs b/src/Hazelcast.Net.Testing/TestData/EmployeeTestObject.cs
index c8496d7cd..a6722aa34 100644
--- a/src/Hazelcast.Net.Testing/TestData/EmployeeTestObject.cs
+++ b/src/Hazelcast.Net.Testing/TestData/EmployeeTestObject.cs
@@ -33,5 +33,18 @@ public DateTime Started
}
public long StartedAtTimeStamp { get; set; }
public char Type { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ if (this == obj) return true;
+ if (obj == null || GetType() != obj.GetType()) return false;
+ var that = (EmployeeTestObject)obj;
+ return Id == that.Id &&
+ Name == that.Name &&
+ Salary.Equals(that.Salary) &&
+ StartedAtTimeStamp == that.StartedAtTimeStamp &&
+ Type == that.Type;
+ }
+
}
}
diff --git a/src/Hazelcast.Net.Tests/CP/CPRoutingTests.cs b/src/Hazelcast.Net.Tests/CP/CPRoutingTests.cs
index 331bcdff8..1a0997202 100644
--- a/src/Hazelcast.Net.Tests/CP/CPRoutingTests.cs
+++ b/src/Hazelcast.Net.Tests/CP/CPRoutingTests.cs
@@ -26,7 +26,7 @@
namespace Hazelcast.Tests.CP
{
[Category("enterprise")]
- [ServerCondition("[5.5)")]
+ [ServerCondition("[5.5,)")]
[Timeout(30_000)]
public class CPRoutingTests : MultiMembersRemoteTestBase
{
diff --git a/src/Hazelcast.Net.Tests/Clustering/ConnectMembersTests.cs b/src/Hazelcast.Net.Tests/Clustering/ConnectMembersTests.cs
index e74e83113..398e96bdd 100644
--- a/src/Hazelcast.Net.Tests/Clustering/ConnectMembersTests.cs
+++ b/src/Hazelcast.Net.Tests/Clustering/ConnectMembersTests.cs
@@ -217,7 +217,7 @@ async Task ConnectMembers(MemberConnectionQueue memberConnectionQueue, Cancellat
{
await foreach (var request in memberConnectionQueue.WithCancellation(cancellationToken))
{
- dequeuedRequests++;
+ Interlocked.Increment(ref dequeuedRequests);
if (!memberCount.TryGetValue(request.Member.Id, out var count)) count = 0;
memberCount[request.Member.Id] = ++count;
logger.LogDebug($"Connect request={dequeuedRequests} member={request.Member.Id.ToShortString()} count={count} result={(count == successCount ? "success" : "failed")}");
@@ -246,9 +246,12 @@ await AssertEx.SucceedsEventually(() =>
cancellation.Cancel();
await connecting.CfAwaitCanceled();
- // each member retried twice = twice the 1s delay = 2s
+ // each member retried twice = twice the ~1s delay ~ 2s
// we should not have completed faster than that, even so the code runs fully in-memory
- Assert.That(elapsed, Is.GreaterThanOrEqualTo(TimeSpan.FromSeconds(2)));
+ // Note: The queue has 10ms error margin per wait, so we take 20ms total margin for two unsuccessful tries
+ var failedCount = successCount - 1;
+ var expectedMinTotalDelay = TimeSpan.FromMilliseconds(failedCount * 990); // 990ms per failed try including 10ms margin
+ Assert.That(elapsed, Is.GreaterThanOrEqualTo(expectedMinTotalDelay));
HConsole.WriteLine(this, $"Elapsed: {elapsed}");
Assert.That(queue.Count, Is.EqualTo(0));
diff --git a/src/Hazelcast.Net.Tests/Hazelcast.Net.Tests.csproj b/src/Hazelcast.Net.Tests/Hazelcast.Net.Tests.csproj
index 5911df0af..8142d84e8 100644
--- a/src/Hazelcast.Net.Tests/Hazelcast.Net.Tests.csproj
+++ b/src/Hazelcast.Net.Tests/Hazelcast.Net.Tests.csproj
@@ -49,21 +49,9 @@
-
-
-
+
+
-
-
-
-
- SystemLinqAsyncEnumerable
-
-
-
-
diff --git a/src/Hazelcast.Net.Tests/Remote/UnisocketTests.cs b/src/Hazelcast.Net.Tests/Remote/UnisocketTests.cs
index 5387c44e4..70dc4d469 100644
--- a/src/Hazelcast.Net.Tests/Remote/UnisocketTests.cs
+++ b/src/Hazelcast.Net.Tests/Remote/UnisocketTests.cs
@@ -126,7 +126,7 @@ public async Task TestClientConnectsToOneMember()
[Test]
- [ServerCondition("[6.0)")]
+ [ServerCondition("5.6.0")]
public async Task TestRoutingModesInOrderWithServer()
{
var script = @"result = com.hazelcast.client.config.RoutingMode.SINGLE_MEMBER.getId() +
@@ -147,7 +147,7 @@ public async Task TestRoutingModesInOrderWithServer()
}
[Test]
- [ServerCondition("[5.5.0,6.0)")]
+ [ServerCondition("[5.5,)")]
public async Task TestRoutingModesInOrderWithServerWithPreviousPackage()
{
var script = @"result = com.hazelcast.client.impl.connection.tcp.RoutingMode.SINGLE_MEMBER.getId() +
diff --git a/src/Hazelcast.Net.Tests/Vector/VectorCollectionTests.cs b/src/Hazelcast.Net.Tests/Vector/VectorCollectionTests.cs
index 04e726514..d101ef05b 100644
--- a/src/Hazelcast.Net.Tests/Vector/VectorCollectionTests.cs
+++ b/src/Hazelcast.Net.Tests/Vector/VectorCollectionTests.cs
@@ -21,7 +21,7 @@
using NUnit.Framework;
namespace Hazelcast.Tests.Vector
{
- [ServerCondition("[5.5.0")]
+ [ServerCondition("5.5")]
[Category("enterprise")]
public class VectorCollectionTests : SingleMemberClientRemoteTestBase
{
diff --git a/src/Hazelcast.Net/Clustering/ClusterEvents.cs b/src/Hazelcast.Net/Clustering/ClusterEvents.cs
index 8e6499e97..503821119 100644
--- a/src/Hazelcast.Net/Clustering/ClusterEvents.cs
+++ b/src/Hazelcast.Net/Clustering/ClusterEvents.cs
@@ -343,7 +343,7 @@ private async Task AddSubscriptionsAsync(MemberConnection connection, IReadOnlyC
}
// we are done now
- lock (_subscribeTasksMutex) _subscribeTasks.Remove(connection);
+ lock (_subscribeTasksMutex) _subscribeTasks?.Remove(connection);
}
///
diff --git a/src/Hazelcast.Net/DistributedObjects/Impl/HVectorCollection.cs b/src/Hazelcast.Net/DistributedObjects/Impl/HVectorCollection.cs
index 6c6352e69..5eb1a479c 100644
--- a/src/Hazelcast.Net/DistributedObjects/Impl/HVectorCollection.cs
+++ b/src/Hazelcast.Net/DistributedObjects/Impl/HVectorCollection.cs
@@ -17,6 +17,7 @@
using System.Threading.Tasks;
using Hazelcast.Clustering;
using Hazelcast.Core;
+using Hazelcast.Messaging;
using Hazelcast.Models;
using Hazelcast.Protocol.Codecs;
using Hazelcast.Serialization;
@@ -67,22 +68,39 @@ public async Task> PutIfAbsentAsync(TKey key, IVectorDocum
var rawResponse = VectorCollectionPutIfAbsentCodec.DecodeResponse(response).Value;
return await DeserializeIVectorDocumentAsync(rawResponse).CfAwait();
}
- public Task PutAllAsync([NotNull] IDictionary> vectorDocumentMap)
+ public async Task PutAllAsync([NotNull] IDictionary> vectorDocumentMap)
{
vectorDocumentMap.ThrowIfNull();
+ var entriesByPartition = new Dictionary>>>();
- var rawEntries = new List>>();
foreach (var kvp in vectorDocumentMap)
{
var key = kvp.Key ?? throw new ArgumentException($"Key cannot be null in {nameof(vectorDocumentMap)}.");
var val = kvp.Value ?? throw new ArgumentException($"Value cannot be null in {nameof(vectorDocumentMap)}.");
- var dataKey = ToSafeData(key);
- var dataValue = ToSafeData(val);
- var rawDocument = new VectorDocument(dataValue, kvp.Value.Vectors);
- rawEntries.Add(new KeyValuePair>(dataKey, rawDocument));
+ var(dataKey, rawDocument) = PrepareForPut(key, val);
+ var partitionId = Cluster.Partitioner.GetPartitionId(dataKey.PartitionHash);
+
+ if (entriesByPartition.TryGetValue(partitionId, out var list))
+ {
+ list.Add(new KeyValuePair>(dataKey, rawDocument));
+ }
+ else
+ {
+ entriesByPartition[partitionId] = new List>>()
+ {
+ new KeyValuePair>(dataKey, rawDocument)
+ };
+ }
}
- var message = VectorCollectionPutAllCodec.EncodeRequest(Name, rawEntries);
- return Cluster.Messaging.SendAsync(message);
+
+ var tasks = new List>();
+ foreach (var entry in entriesByPartition)
+ {
+ var message = VectorCollectionPutAllCodec.EncodeRequest(Name, entry.Value);
+ tasks.Add(Cluster.Messaging.SendToPartitionOwnerAsync(message, entry.Key));
+ }
+
+ await Task.WhenAll(tasks).CfAwait();
}
public async Task> RemoveAsync(TKey key)
{
@@ -143,7 +161,7 @@ private async Task> DeserializeIVectorDocumentAsync(
{
return null;
}
-
+
var userObject = await ToObjectAsync(rawResponse.Value).CfAwait();
return new VectorDocument(userObject, rawResponse.Vectors);
}
diff --git a/src/Hazelcast.Net/Hazelcast.Net.csproj b/src/Hazelcast.Net/Hazelcast.Net.csproj
index 75d5a0582..f7a7eb4a3 100644
--- a/src/Hazelcast.Net/Hazelcast.Net.csproj
+++ b/src/Hazelcast.Net/Hazelcast.Net.csproj
@@ -68,7 +68,7 @@
-
+
diff --git a/src/Hazelcast.Net/Models/SingleVectorValues.cs b/src/Hazelcast.Net/Models/SingleVectorValues.cs
index bbd132cb8..882e6503c 100644
--- a/src/Hazelcast.Net/Models/SingleVectorValues.cs
+++ b/src/Hazelcast.Net/Models/SingleVectorValues.cs
@@ -11,7 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-using Hazelcast.Serialization;
+using System.Linq;
namespace Hazelcast.Models
{
public class SingleVectorValues : VectorValues
@@ -22,12 +22,22 @@ internal SingleVectorValues(float[] vector)
Vector = vector;
}
public float[] Vector { get; }
-
+
+
+ ///
public override string ToString()
{
var val = Vector == null ? "null" : $"[{string.Join(", ", Vector)}]";
return $"SingleVectorValues{{vector={val}}}";
}
+ ///
+ public override bool Equals(object obj)
+ {
+ if (this == obj) return true;
+ if (obj == null || GetType() != obj.GetType()) return false;
+ var that = (SingleVectorValues)obj;
+ return Vector.SequenceEqual(that.Vector);
+ }
}
}
diff --git a/src/Hazelcast.Net/Models/VectorSearchOptions.cs b/src/Hazelcast.Net/Models/VectorSearchOptions.cs
index 9ede16314..4d73e1582 100644
--- a/src/Hazelcast.Net/Models/VectorSearchOptions.cs
+++ b/src/Hazelcast.Net/Models/VectorSearchOptions.cs
@@ -34,7 +34,7 @@ public VectorSearchOptions(bool includeValue = default,
IncludeValue = includeValue;
IncludeVectors = includeVectors;
Limit = limit;
- Hints = hints;
+ Hints = hints ?? new Dictionary();
}
///
diff --git a/src/Hazelcast.Net/PublicAPI/PublicAPI.Shipped.txt b/src/Hazelcast.Net/PublicAPI/PublicAPI.Shipped.txt
index 931c268de..06c38c3c2 100644
--- a/src/Hazelcast.Net/PublicAPI/PublicAPI.Shipped.txt
+++ b/src/Hazelcast.Net/PublicAPI/PublicAPI.Shipped.txt
@@ -2653,4 +2653,5 @@ override Hazelcast.Models.ClusterVersion.GetHashCode() -> int
~Hazelcast.Networking.NetworkingOptions.RoutingMode.get -> Hazelcast.Networking.RoutingMode
~override Hazelcast.Models.ClusterVersion.Equals(object obj) -> bool
~override Hazelcast.Models.ClusterVersion.ToString() -> string
-~static Hazelcast.Models.ClusterVersion.Parse(string value) -> Hazelcast.Models.ClusterVersion
\ No newline at end of file
+~static Hazelcast.Models.ClusterVersion.Parse(string value) -> Hazelcast.Models.ClusterVersion
+~override Hazelcast.Models.SingleVectorValues.Equals(object obj) -> bool
\ No newline at end of file
diff --git a/src/Hazelcast.Net/PublicAPI/net10.0/PublicAPI.Shipped.txt b/src/Hazelcast.Net/PublicAPI/net10.0/PublicAPI.Shipped.txt
index 12001093c..4daf08313 100644
--- a/src/Hazelcast.Net/PublicAPI/net10.0/PublicAPI.Shipped.txt
+++ b/src/Hazelcast.Net/PublicAPI/net10.0/PublicAPI.Shipped.txt
@@ -2711,3 +2711,4 @@ virtual Hazelcast.Serialization.Compact.CompactSerializerBase.TypeName.get ->
~virtual Hazelcast.Query.PredicateBuilder.IsLike(string pattern) -> Hazelcast.Query.IPredicate
~virtual Hazelcast.Query.PredicateBuilder.IsNotEqualTo(object value) -> Hazelcast.Query.IPredicate
~virtual Hazelcast.Query.PredicateBuilder.Matches(string regex) -> Hazelcast.Query.IPredicate
+~override Hazelcast.Models.SingleVectorValues.Equals(object obj) -> bool
\ No newline at end of file
diff --git a/src/Hazelcast.Net/PublicAPI/net8.0/PublicAPI.Shipped.txt b/src/Hazelcast.Net/PublicAPI/net8.0/PublicAPI.Shipped.txt
index 12001093c..4daf08313 100644
--- a/src/Hazelcast.Net/PublicAPI/net8.0/PublicAPI.Shipped.txt
+++ b/src/Hazelcast.Net/PublicAPI/net8.0/PublicAPI.Shipped.txt
@@ -2711,3 +2711,4 @@ virtual Hazelcast.Serialization.Compact.CompactSerializerBase.TypeName.get ->
~virtual Hazelcast.Query.PredicateBuilder.IsLike(string pattern) -> Hazelcast.Query.IPredicate
~virtual Hazelcast.Query.PredicateBuilder.IsNotEqualTo(object value) -> Hazelcast.Query.IPredicate
~virtual Hazelcast.Query.PredicateBuilder.Matches(string regex) -> Hazelcast.Query.IPredicate
+~override Hazelcast.Models.SingleVectorValues.Equals(object obj) -> bool
\ No newline at end of file
diff --git a/src/Hazelcast.Net/PublicAPI/net9.0/PublicAPI.Shipped.txt b/src/Hazelcast.Net/PublicAPI/net9.0/PublicAPI.Shipped.txt
index 12001093c..4daf08313 100644
--- a/src/Hazelcast.Net/PublicAPI/net9.0/PublicAPI.Shipped.txt
+++ b/src/Hazelcast.Net/PublicAPI/net9.0/PublicAPI.Shipped.txt
@@ -2711,3 +2711,4 @@ virtual Hazelcast.Serialization.Compact.CompactSerializerBase.TypeName.get ->
~virtual Hazelcast.Query.PredicateBuilder.IsLike(string pattern) -> Hazelcast.Query.IPredicate
~virtual Hazelcast.Query.PredicateBuilder.IsNotEqualTo(object value) -> Hazelcast.Query.IPredicate
~virtual Hazelcast.Query.PredicateBuilder.Matches(string regex) -> Hazelcast.Query.IPredicate
+~override Hazelcast.Models.SingleVectorValues.Equals(object obj) -> bool
\ No newline at end of file
diff --git a/src/Hazelcast.Net/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt b/src/Hazelcast.Net/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt
index 776f4142a..1cd904f7b 100644
--- a/src/Hazelcast.Net/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt
+++ b/src/Hazelcast.Net/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt
@@ -2711,5 +2711,5 @@ virtual Hazelcast.Serialization.Compact.CompactSerializerBase.TypeName.get ->
~virtual Hazelcast.Query.PredicateBuilder.IsLike(string pattern) -> Hazelcast.Query.IPredicate
~virtual Hazelcast.Query.PredicateBuilder.IsNotEqualTo(object value) -> Hazelcast.Query.IPredicate
~virtual Hazelcast.Query.PredicateBuilder.Matches(string regex) -> Hazelcast.Query.IPredicate
-
+~override Hazelcast.Models.SingleVectorValues.Equals(object obj) -> bool
diff --git a/src/Hazelcast.Net/PublicAPI/netstandard2.1/PublicAPI.Shipped.txt b/src/Hazelcast.Net/PublicAPI/netstandard2.1/PublicAPI.Shipped.txt
index b24f79f48..7a20fbc77 100644
--- a/src/Hazelcast.Net/PublicAPI/netstandard2.1/PublicAPI.Shipped.txt
+++ b/src/Hazelcast.Net/PublicAPI/netstandard2.1/PublicAPI.Shipped.txt
@@ -2711,5 +2711,5 @@ virtual Hazelcast.Serialization.Compact.CompactSerializerBase.TypeName.get ->
~virtual Hazelcast.Query.PredicateBuilder.IsLike(string pattern) -> Hazelcast.Query.IPredicate
~virtual Hazelcast.Query.PredicateBuilder.IsNotEqualTo(object value) -> Hazelcast.Query.IPredicate
~virtual Hazelcast.Query.PredicateBuilder.Matches(string regex) -> Hazelcast.Query.IPredicate
-
+~override Hazelcast.Models.SingleVectorValues.Equals(object obj) -> bool