public void NoInfiniteRetriesTest() { byte[] defaultData = new byte[] { 1, 2, 3 }; var data = new ConcurrentDictionary <BobKey, byte[]>(); var behaviour1 = new BobNodeClientMockHelper.MockClientBehaviour(); var stat1 = new BobNodeClientMockHelper.MockClientStat(); var behaviour2 = new BobNodeClientMockHelper.MockClientBehaviour(); var stat2 = new BobNodeClientMockHelper.MockClientStat(); BobNodeClient[] clients = new BobNodeClient[] { BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour: behaviour1, stat: stat1), BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour: behaviour2, stat: stat2) }; behaviour1.ErrorStatus = new Grpc.Core.Status(Grpc.Core.StatusCode.Internal, "Internal error"); behaviour2.ErrorStatus = new Grpc.Core.Status(Grpc.Core.StatusCode.Internal, "Internal error"); using (var client = new BobClusterClient(clients, SequentialNodeSelectionPolicy.Factory, operationRetryCount: 10)) { Assert.Throws <BobOperationException>(() => client.Put(BobKey.FromUInt64(1), defaultData)); Assert.Throws <BobOperationException>(() => client.Get(BobKey.FromUInt64(1))); } }
public void ConnectingStateTest() { var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = new byte[] { 1, 2, 3 }; var behaviour = new BobNodeClientMockHelper.MockClientBehaviour(); using (var client = BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour)) { Assert.Equal(BobNodeClientState.Idle, client.State); behaviour.Pause.Reset(); Task asyncOp = Task.Factory.StartNew(() => client.Open(), TaskCreationOptions.LongRunning); for (int i = 0; i < 1000 && client.State == BobNodeClientState.Idle; i++) { Thread.Sleep(10); } Assert.Equal(BobNodeClientState.Connecting, client.State); behaviour.Pause.Set(); asyncOp.Wait(); Assert.Equal(BobNodeClientState.Ready, client.State); } }
public void KeyNotFoundIsNotCountingAsErrors() { var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = new byte[] { 1, 2, 3 }; var behaviour = new BobNodeClientMockHelper.MockClientBehaviour(); var stat = new BobNodeClientMockHelper.MockClientStat(); using (var client = BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour, stat)) { client.Open(); Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); try { client.Get(BobKey.FromUInt64(100)); } catch (BobKeyNotFoundException) { } Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); } }
public void TimeoutIsNotCountingAsErrors() { var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = new byte[] { 1, 2, 3 }; var behaviour = new BobNodeClientMockHelper.MockClientBehaviour(); var stat = new BobNodeClientMockHelper.MockClientStat(); using (var client = BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour, stat)) { client.Open(); Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); try { behaviour.ErrorStatus = new Grpc.Core.Status(Grpc.Core.StatusCode.DeadlineExceeded, "Deadline"); client.Get(BobKey.FromUInt64(1)); } catch (TimeoutException) { } Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); } }
public void ConnectingToFailedStateTest() { var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = new byte[] { 1, 2, 3 }; var behaviour = new BobNodeClientMockHelper.MockClientBehaviour(); using (var client = BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour)) { Assert.Equal(BobNodeClientState.Idle, client.State); behaviour.Pause.Reset(); behaviour.ErrorStatus = new Grpc.Core.Status(Grpc.Core.StatusCode.Internal, "Internal error"); Task asyncOp = Task.Factory.StartNew(() => { try { client.Open(); } catch { } }, TaskCreationOptions.LongRunning); for (int i = 0; i < 1000 && client.State == BobNodeClientState.Idle; i++) { Thread.Sleep(10); } Assert.Equal(BobNodeClientState.Connecting, client.State); behaviour.Pause.Set(); asyncOp.Wait(); Assert.Equal(BobNodeClientState.TransientFailure, client.State); } }
public void ToUInt64FromUInt64Test(ulong key) { var bobKey = BobKey.FromUInt64(key); ulong convKey = bobKey.ToUInt64(); Assert.Equal(key, convKey); }
public void TimeSinceLastOperationTest() { var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = new byte[] { 1, 2, 3 }; var behaviour = new BobNodeClientMockHelper.MockClientBehaviour(); var stat = new BobNodeClientMockHelper.MockClientStat(); using (var client = BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour, stat)) { client.Open(); client.Put(BobKey.FromUInt64(10), new byte[] { 1, 2, 3 }); int startTick = Environment.TickCount; for (int i = 0; i < 100; i++) { Thread.Sleep(10); int elapsed = unchecked (Environment.TickCount - startTick); Assert.InRange(client.TimeSinceLastOperationMs, elapsed - 10, elapsed + 100); } client.Get(BobKey.FromUInt64(10)); Assert.True(client.TimeSinceLastOperationMs < 100); } }
public void OperationTimeoutIsUsedTest() { var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = new byte[] { 1, 2, 3 }; DateTime?deadline = null; var mock = BobNodeClientMockHelper.CreateDataAccessMockedBobApiClient(data, new BobNodeClientMockHelper.MockClientBehaviour(), new BobNodeClientMockHelper.MockClientStat(), getFunc: (req, opt) => { deadline = opt.Deadline; return(new BobStorage.Blob() { Data = Google.Protobuf.ByteString.CopyFrom(new byte[] { 1, 2, 3 }) }); }); using (var client = BobNodeClientMockHelper.CreateMockedClient("Address = 127.0.0.1; OperationTimeout = 01:00:00", mock)) { var expectedDeadline = DateTime.UtcNow + TimeSpan.FromHours(1); client.Get(BobKey.FromUInt64(1)); Assert.NotNull(deadline); var delta = (deadline.Value - expectedDeadline); if (delta < TimeSpan.Zero) { delta = -delta; } Assert.True(delta < TimeSpan.FromMinutes(10)); } }
public void ToUInt64Test(byte[] k, ulong expected) { var bobKey = new BobKey(k); ulong convKey = bobKey.ToUInt64(); Assert.Equal(expected, convKey); }
public void ToStringTest(ulong value, string expectedStr) { var key = BobKey.FromUInt64(value); string stringVal = key.ToString(); Assert.Equal(expectedStr, stringVal); }
/// <summary> /// Selects one of the node from cluster to perform operation /// </summary> /// <param name="operation">Operation for which the node selection is performing</param> /// <param name="key">Key for which the node selection is performing (can be empty)</param> /// <returns>Index of the selected node</returns> public override int SelectNodeIndex(BobOperationKind operation, BobKey key) { int lastActiveNode = _lastActiveNode; if (lastActiveNode < Nodes.Count && CanBeUsed(Nodes[lastActiveNode])) { return(lastActiveNode); } int testingNode = lastActiveNode; for (int i = 1; i < Nodes.Count; i++) { testingNode = (testingNode + 1) % Nodes.Count; if (CanBeUsed(Nodes[testingNode])) { System.Threading.Interlocked.CompareExchange(ref _lastActiveNode, testingNode, lastActiveNode); return(testingNode); } } // Select next node to prevent stucking on a single when all nodes are unavailable testingNode = (lastActiveNode + 1) % Nodes.Count; System.Threading.Interlocked.CompareExchange(ref _lastActiveNode, testingNode, lastActiveNode); return(testingNode); }
public void CancellationIsNotCountingAsErrors() { var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = new byte[] { 1, 2, 3 }; var behaviour = new BobNodeClientMockHelper.MockClientBehaviour(); var stat = new BobNodeClientMockHelper.MockClientStat(); using (var client = BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour, stat)) { client.Open(); Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); try { CancellationTokenSource cancelled = new CancellationTokenSource(); cancelled.Cancel(); client.Get(BobKey.FromUInt64(1), cancelled.Token); } catch (OperationCanceledException) { } Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); } }
/// <summary> /// Selects one of the node from cluster to perform operation /// </summary> /// <param name="operation">Operation for which the node selection is performing</param> /// <param name="key">Key for which the node selection is performing (can be empty)</param> /// <returns>Index of the selected node</returns> public override int SelectNodeIndex(BobOperationKind operation, BobKey key) { var nodes = this.Nodes; if (nodes.Count == 1) { return(0); } int indexRawValue = Interlocked.Increment(ref _index); int index = (indexRawValue & int.MaxValue) % nodes.Count; if (CanBeUsed(nodes[index])) { return(index); } for (int repCnt = 1; repCnt < nodes.Count; repCnt++) { index = (index + 1) % nodes.Count; if (CanBeUsed(nodes[index])) { Interlocked.CompareExchange(ref _index, index, indexRawValue); return(index); } } // Fallback to one-by-one stepping (_index was incremented at the beggining) return((indexRawValue & int.MaxValue) % nodes.Count); }
public async Task BasicStateTransitionTestAsync() { var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = new byte[] { 1, 2, 3 }; var stat = new BobNodeClientMockHelper.MockClientStat(); using (var client = BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour: null, stat: stat)) { Assert.Equal(BobNodeClientState.Idle, client.State); Assert.Equal(0, client.SequentialErrorCount); await client.OpenAsync(); Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); Assert.True(client.TimeSinceLastOperationMs < 10000); await client.PutAsync(BobKey.FromUInt64(2), new byte[] { 1, 2, 3 }); Assert.Equal(1, stat.PutRequestCount); Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); Assert.True(client.TimeSinceLastOperationMs < 10000); var testDataArray = await client.GetAsync(BobKey.FromUInt64(2)); Assert.Equal(1, stat.GetRequestCount); Assert.Equal(new byte[] { 1, 2, 3 }, testDataArray); Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); Assert.True(client.TimeSinceLastOperationMs < 10000); var existsResult = await client.ExistsAsync(new BobKey[] { BobKey.FromUInt64(1), BobKey.FromUInt64(2), BobKey.FromUInt64(3) }); Assert.Equal(1, stat.ExistsRequestCount); Assert.Equal(new bool[] { true, true, false }, existsResult); Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); Assert.True(client.TimeSinceLastOperationMs < 10000); var existsResult2 = await client.ExistsAsync(new List <BobKey>() { BobKey.FromUInt64(1), BobKey.FromUInt64(2), BobKey.FromUInt64(3) }); Assert.Equal(2, stat.ExistsRequestCount); Assert.Equal(new bool[] { true, true, false }, existsResult2); Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); Assert.True(client.TimeSinceLastOperationMs < 10000); await client.CloseAsync(); Assert.Equal(BobNodeClientState.Shutdown, client.State); Assert.Equal(0, client.SequentialErrorCount); } }
public void PutGetExistOperationUInt64ConcurrentTest(int threadCount) { byte[] defaultData = new byte[] { 1, 2, 3 }; var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = defaultData; data[BobKey.FromUInt64(ulong.MaxValue)] = defaultData; using (var client = new BobNodeClient <ulong>(BobNodeClientMockHelper.CreateMockedClientWithData(data), null, null)) { Barrier bar = new Barrier(threadCount + 1); void MainAction() { bar.SignalAndWait(10000); Assert.Equal(defaultData, client.Get(1)); Assert.Equal(defaultData, client.Get(ulong.MaxValue)); Assert.Throws <BobKeyNotFoundException>(() => client.Get(2)); Assert.Equal(new bool[] { true, false }, client.Exists(new ulong[] { 1, 2 })); for (ulong i = 100; i < 10000; i++) { client.Put(i, defaultData); } for (ulong i = 100; i < 10000; i++) { Assert.Equal(defaultData, client.Get(i)); } Assert.All(client.Exists(Enumerable.Range(100, 10000 - 100).Select(o => (ulong)o).ToArray()), res => Assert.True(res)); Assert.All(client.Exists(Enumerable.Range(20000, 1000).Select(o => (ulong)o).ToArray()), res => Assert.False(res)); for (ulong i = uint.MaxValue; i < (ulong)uint.MaxValue + 1000; i++) { client.Put(i, defaultData); } for (ulong i = uint.MaxValue; i < (ulong)uint.MaxValue + 1000; i++) { Assert.Equal(defaultData, client.Get(i)); } } Task[] tasks = new Task[threadCount]; for (int i = 0; i < tasks.Length; i++) { tasks[i] = Task.Factory.StartNew(MainAction, TaskCreationOptions.LongRunning); } bar.SignalAndWait(10000); Task.WaitAll(tasks); } }
public async Task RetriesWorksTestAsync() { byte[] defaultData = new byte[] { 1, 2, 3 }; var data = new ConcurrentDictionary <BobKey, byte[]>(); var behaviour1 = new BobNodeClientMockHelper.MockClientBehaviour(); var stat1 = new BobNodeClientMockHelper.MockClientStat(); var behaviour2 = new BobNodeClientMockHelper.MockClientBehaviour(); var stat2 = new BobNodeClientMockHelper.MockClientStat(); BobNodeClient[] clients = new BobNodeClient[] { BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour: behaviour1, stat: stat1), BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour: behaviour2, stat: stat2) }; behaviour1.ErrorStatus = new Grpc.Core.Status(Grpc.Core.StatusCode.Internal, "Internal error"); using (var client = new BobClusterClient(clients, SequentialNodeSelectionPolicy.Factory, operationRetryCount: 1)) { await client.PutAsync(BobKey.FromUInt64(1), defaultData); Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64(1))); Assert.True((await client.ExistsAsync(new BobKey[] { BobKey.FromUInt64(1) }))[0]); for (int i = 10; i < 100; i++) { await client.PutAsync(BobKey.FromUInt64((ulong)i), defaultData); } for (int i = 10; i < 100; i++) { Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64((ulong)i))); } for (int i = 10; i < 100; i++) { Assert.True((await client.ExistsAsync(new BobKey[] { BobKey.FromUInt64((ulong)i) }))[0]); } } }
public void PutGetExistOperationUInt64Test() { byte[] defaultData = new byte[] { 1, 2, 3 }; var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = defaultData; data[BobKey.FromUInt64(ulong.MaxValue)] = defaultData; using (var client = new BobNodeClient <ulong>(BobNodeClientMockHelper.CreateMockedClientWithData(data), null, null)) { Assert.Equal(defaultData, client.Get(1)); Assert.Equal(defaultData, client.Get(ulong.MaxValue)); Assert.Throws <BobKeyNotFoundException>(() => client.Get(2)); Assert.Equal(new bool[] { true, false }, client.Exists(new ulong[] { 1, 2 })); for (ulong i = 100; i < 10000; i++) { client.Put(i, defaultData); } for (ulong i = 100; i < 10000; i++) { Assert.Equal(defaultData, client.Get(i)); } Assert.All(client.Exists(Enumerable.Range(100, 10000 - 100).Select(o => (ulong)o).ToArray()), res => Assert.True(res)); Assert.All(client.Exists(Enumerable.Range(20000, 1000).Select(o => (ulong)o).ToArray()), res => Assert.False(res)); Assert.All(client.Exists(Enumerable.Range(100, 10000 - 100).Select(o => (ulong)o).ToList()), res => Assert.True(res)); Assert.All(client.Exists(Enumerable.Range(20000, 1000).Select(o => (ulong)o).ToList()), res => Assert.False(res)); for (ulong i = uint.MaxValue; i < (ulong)uint.MaxValue + 1000; i++) { client.Put(i, defaultData); } for (ulong i = uint.MaxValue; i < (ulong)uint.MaxValue + 1000; i++) { Assert.Equal(defaultData, client.Get(i)); } } }
public void NoRetryForKeyNotFoundTest() { byte[] defaultData = new byte[] { 1, 2, 3 }; var data = new ConcurrentDictionary <BobKey, byte[]>(); var behaviour1 = new BobNodeClientMockHelper.MockClientBehaviour(); var stat1 = new BobNodeClientMockHelper.MockClientStat(); var behaviour2 = new BobNodeClientMockHelper.MockClientBehaviour(); var stat2 = new BobNodeClientMockHelper.MockClientStat(); BobNodeClient[] clients = new BobNodeClient[] { BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour: behaviour1, stat: stat1), BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour: behaviour2, stat: stat2) }; using (var client = new BobClusterClient(clients, SequentialNodeSelectionPolicy.Factory, operationRetryCount: 10)) { Assert.Throws <BobKeyNotFoundException>(() => client.Get(BobKey.FromUInt64(1))); Assert.Equal(1, stat1.GetRequestCount + stat2.GetRequestCount); Assert.Throws <BobKeyNotFoundException>(() => client.Get(BobKey.FromUInt64(2))); Assert.Equal(2, stat1.GetRequestCount + stat2.GetRequestCount); Assert.Throws <BobKeyNotFoundException>(() => client.Get(BobKey.FromUInt64(3))); Assert.Equal(3, stat1.GetRequestCount + stat2.GetRequestCount); Assert.Throws <BobKeyNotFoundException>(() => client.GetAsync(BobKey.FromUInt64(1)).GetAwaiter().GetResult()); Assert.Equal(4, stat1.GetRequestCount + stat2.GetRequestCount); Assert.Throws <BobKeyNotFoundException>(() => client.GetAsync(BobKey.FromUInt64(2)).GetAwaiter().GetResult()); Assert.Equal(5, stat1.GetRequestCount + stat2.GetRequestCount); Assert.Throws <BobKeyNotFoundException>(() => client.GetAsync(BobKey.FromUInt64(3)).GetAwaiter().GetResult()); Assert.Equal(6, stat1.GetRequestCount + stat2.GetRequestCount); } }
public async Task PutGetExistOperationTestAsync() { byte[] defaultData = new byte[] { 1, 2, 3 }; var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = defaultData; data[BobKey.FromUInt64(ulong.MaxValue)] = defaultData; using (var client = BobNodeClientMockHelper.CreateMockedClientWithData(data)) { Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64(1))); Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64(ulong.MaxValue))); Assert.Throws <BobKeyNotFoundException>(() => client.GetAsync(BobKey.FromUInt64(2)).GetAwaiter().GetResult()); Assert.Equal(new bool[] { true, false }, await client.ExistsAsync(new BobKey[] { BobKey.FromUInt64(1), BobKey.FromUInt64(2) })); for (ulong i = 100; i < 10000; i++) { await client.PutAsync(BobKey.FromUInt64(i), defaultData); } for (ulong i = 100; i < 10000; i++) { Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64(i))); } Assert.All(await client.ExistsAsync(Enumerable.Range(100, 10000 - 100).Select(o => BobKey.FromUInt64((ulong)o)).ToArray()), res => Assert.True(res)); Assert.All(await client.ExistsAsync(Enumerable.Range(20000, 1000).Select(o => BobKey.FromUInt64((ulong)o)).ToArray()), res => Assert.False(res)); for (ulong i = uint.MaxValue; i < (ulong)uint.MaxValue + 1000; i++) { await client.PutAsync(BobKey.FromUInt64(i), defaultData); } for (ulong i = uint.MaxValue; i < (ulong)uint.MaxValue + 1000; i++) { Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64(i))); } } }
public void SequentialErrorCountTest() { var data = new ConcurrentDictionary <BobKey, byte[]>(); data[BobKey.FromUInt64(1)] = new byte[] { 1, 2, 3 }; var behaviour = new BobNodeClientMockHelper.MockClientBehaviour(); var stat = new BobNodeClientMockHelper.MockClientStat(); using (var client = BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour, stat)) { client.Open(); Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); behaviour.ErrorStatus = new Grpc.Core.Status(Grpc.Core.StatusCode.Internal, "Internal error"); for (int i = 1; i <= 100; i++) { try { client.Get(BobKey.FromUInt64(1)); } catch (BobOperationException) { } Assert.Equal(BobNodeClientState.TransientFailure, client.State); Assert.Equal(i, client.SequentialErrorCount); } behaviour.ErrorStatus = Grpc.Core.Status.DefaultSuccess; client.Get(BobKey.FromUInt64(1)); Assert.Equal(BobNodeClientState.Ready, client.State); Assert.Equal(0, client.SequentialErrorCount); } }
/// <summary> /// Selects one of the node from cluster to retry previously failed operation (may return negative value to stop trying) /// </summary> /// <param name="prevNodeIndex">Previously selected node index</param> /// <param name="operation">Operation for which the node selection is performing</param> /// <param name="key">Key for which the node selection is performing (can be empty)</param> /// <returns>Index of the selected node or -1 to stop trying</returns> public override int SelectNodeIndexOnRetry(int prevNodeIndex, BobOperationKind operation, BobKey key) { var nodes = this.Nodes; if (nodes.Count == 1) { return(-1); } int index = prevNodeIndex; for (int repCnt = 1; repCnt < nodes.Count; repCnt++) { index = (index + 1) % nodes.Count; if (CanBeUsed(nodes[index])) { return(index); } } return(-1); }
/// <summary> /// Selects one of the node from cluster to retry previously failed operation (may return negative value to stop trying) /// </summary> /// <param name="prevNodeIndex">Previously selected node index</param> /// <param name="operation">Operation for which the node selection is performing</param> /// <param name="key">Key for which the node selection is performing (can be empty)</param> /// <returns>Index of the selected node or -1 to stop trying</returns> public override int SelectNodeIndexOnRetry(int prevNodeIndex, BobOperationKind operation, BobKey key) { int testingNode = prevNodeIndex; for (int i = 1; i < Nodes.Count; i++) { testingNode = (testingNode + 1) % Nodes.Count; if (CanBeUsed(Nodes[testingNode])) { return(testingNode); } } return(-1); }
/// <summary> /// Selects one of the node from cluster to retry previously failed operation (may return negative value to stop trying) /// </summary> /// <param name="prevNodeIndex">Previously selected node index</param> /// <param name="operation">Operation for which the node selection is performing</param> /// <param name="key">Key for which the node selection is performing (can be empty)</param> /// <returns>Index of the selected node or -1 to stop trying</returns> public override int SelectNodeIndexOnRetry(int prevNodeIndex, BobOperationKind operation, BobKey key) { return(0); }
/// <summary> /// Selects one of the node from cluster to perform operation /// </summary> /// <param name="operation">Operation for which the node selection is performing</param> /// <param name="key">Key for which the node selection is performing (can be empty)</param> /// <returns>Index of the selected node</returns> public override int SelectNodeIndex(BobOperationKind operation, BobKey key) { return(0); }
public void GetHashCodeTest(byte[] k1) { int hashCode = new BobKey(k1).GetHashCode(); Assert.True(hashCode != 0); }
public void RemainderTest(ulong key, int divisor) { Assert.Equal((long)key % divisor, BobKey.FromUInt64(key).Remainder(divisor)); }
/// <summary> /// Selects one of the node from cluster to perform operation /// </summary> /// <param name="operation">Operation for which the node selection is performing</param> /// <param name="key">Key for which the node selection is performing (can be empty)</param> /// <returns>Index of the selected node</returns> public abstract int SelectNodeIndex(BobOperationKind operation, BobKey key);
/// <summary> /// Selects one of the node from cluster to retry previously failed operation (may return negative value to stop trying) /// </summary> /// <param name="prevNodeIndex">Previously selected node index</param> /// <param name="operation">Operation for which the node selection is performing</param> /// <param name="key">Key for which the node selection is performing (can be empty)</param> /// <returns>Index of the selected node or -1 to stop trying</returns> public abstract int SelectNodeIndexOnRetry(int prevNodeIndex, BobOperationKind operation, BobKey key);
public async Task PutGetExistOperationTestAsync() { byte[] defaultData = new byte[] { 1, 2, 3 }; var data = new ConcurrentDictionary <BobKey, byte[]>(); var stat1 = new BobNodeClientMockHelper.MockClientStat(); var stat2 = new BobNodeClientMockHelper.MockClientStat(); BobNodeClient[] clients = new BobNodeClient[] { BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour: null, stat: stat1), BobNodeClientMockHelper.CreateMockedClientWithData(data, behaviour: null, stat: stat2) }; using (var client = new BobClusterClient(clients, SequentialNodeSelectionPolicy.Factory, 0)) { await client.PutAsync(BobKey.FromUInt64(1), defaultData); await client.PutAsync(BobKey.FromUInt64(ulong.MaxValue), defaultData); Assert.Equal(2, stat1.PutRequestCount + stat2.PutRequestCount); Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64(1))); Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64(ulong.MaxValue))); await Assert.ThrowsAsync <BobKeyNotFoundException>(() => client.GetAsync(BobKey.FromUInt64(2))); Assert.Equal(3, stat1.GetRequestCount + stat2.GetRequestCount); Assert.Equal(new bool[] { true, false }, await client.ExistsAsync(new BobKey[] { BobKey.FromUInt64(1), BobKey.FromUInt64(2) })); Assert.Equal(1, stat1.ExistsRequestCount + stat2.ExistsRequestCount); for (ulong i = 100; i < 10000; i++) { await client.PutAsync(BobKey.FromUInt64(i), defaultData); } for (ulong i = 100; i < 10000; i++) { Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64(i))); } for (ulong i = 100; i < 10000; i++) { Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64(i), fullGet: true, new CancellationToken())); } Assert.Equal(10000 - 100, stat1.RequestsWithFullGet + stat2.RequestsWithFullGet); Assert.All(await client.ExistsAsync(Enumerable.Range(100, 10000 - 100).Select(o => BobKey.FromUInt64((ulong)o)).ToArray()), res => Assert.True(res)); Assert.All(await client.ExistsAsync(Enumerable.Range(20000, 1000).Select(o => BobKey.FromUInt64((ulong)o)).ToArray(), fullGet: true, new CancellationToken()), res => Assert.False(res)); Assert.Equal(10000 - 100 + 1, stat1.RequestsWithFullGet + stat2.RequestsWithFullGet); for (ulong i = uint.MaxValue; i < (ulong)uint.MaxValue + 1000; i++) { await client.PutAsync(BobKey.FromUInt64(i), defaultData); } for (ulong i = uint.MaxValue; i < (ulong)uint.MaxValue + 1000; i++) { Assert.Equal(defaultData, await client.GetAsync(BobKey.FromUInt64(i))); } Assert.True(stat1.RequestsWithFullGet + stat2.RequestsWithFullGet > 0); Assert.True(stat1.TotalRequestCount > 0); Assert.True(stat2.TotalRequestCount > 0); Assert.True(Math.Abs(stat1.TotalRequestCount - stat2.TotalRequestCount) <= 1); } }
/// <summary> /// Deserialize <see cref="BobKey"/> to key of type <typeparamref name="TKey"/> /// </summary> /// <param name="bobKey">Bob key</param> /// <returns>Deserialized key</returns> internal TKey DeserializeFromBobKey(BobKey bobKey) { return(Deserialize(bobKey.GetKeyBytes())); }