public static void SequentialTest() { ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); var m = new MemoryQueue(); int taskCount = 100; ITask[] tasks = new ITask[taskCount]; PromiseTaskResultHandle <int>[] handles = new PromiseTaskResultHandle <int> [taskCount]; for (int i = 0; i < taskCount; i++) { var add = new AddTask(new (i, i + 1)); tasks[i] = add; var handle = new PromiseTaskResultHandle <int>(add, redis, (o) => Console.WriteLine($"result is ready: {o}")); add.BindPromise(handle.GetPromise()); m.Enqueue(add.Serialize()); handles[i] = handle; } var resolver = new RedisPromiseServer(redis); // promises resolved in a sequential manner. like one worker is processing all of them for (int i = 0; i < taskCount; i++) { var task = new DefaultTaskDeserializer().Deserialize((string)m.Dequeue()); task.Execute(); var res = task.SerializeResult(); // thanks to BindPromise each task's instance id is also id of its related promise. So we can directly resolve related promise by using it. resolver.Resolve(task.GetInstanceIdentifier(), res); } Thread.Sleep(1000); }
public static void CreatePromiseTest() { ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); var m = new MemoryQueue(); int taskCount = 100; ITask[] tasks = new ITask[taskCount]; PromiseTaskResultHandle <int>[] handles = new PromiseTaskResultHandle <int> [taskCount]; for (int i = 0; i < taskCount; i++) { var add = new AddTask(new (i, i + 1)); tasks[i] = add; var client = RedisPromiseClientFactory.GetInstance(redis); var promise = client.CreatePromise(); add.BindPromise(promise); var handle = new PromiseTaskResultHandle <int>(add, promise, (o) => Console.WriteLine($"result is ready: {o}")); //now promise will be ready to resolve client.Listen(promise); m.Enqueue(add.Serialize()); handles[i] = handle; } var resolver = new RedisPromiseServer(redis); // this is simulating many workers are resolving promises. (executing tasks in this context) Parallel.ForEach(handles, ((handle) => { var task = new DefaultTaskDeserializer().Deserialize((string)m.Dequeue()); task.Execute(); var res = task.SerializeResult(); // thanks to BindPromise each task's instance id is also id of its related promise. So we can directly resolve related promise by using it. resolver.Resolve(task.GetInstanceIdentifier(), res); })); for (int i = 0; i < taskCount; i++) { int correctResult = i + i + 1; while (!handles[i].IsResolved()) { // it might not come from redis yet Thread.Sleep(10); } var calculatedResult = (int)handles[i].GetObjectResult(); if (correctResult != calculatedResult) { throw new Exception("wrong result"); } } Console.WriteLine("ParallelTest is Successful"); Thread.Sleep(1000); }
public void MemoryQueue_Dequeue_NoItem() { var queue = new MemoryQueue(); Assert.AreEqual(0, queue.Count, "Expected zero Entries in the queue."); var entry = queue.Dequeue(); Assert.IsNull(entry, "Dequeue did not return back null when it had zero entries."); }
public void ShouldDequeue() { MemoryQueue<MyTestObject> queue = new MemoryQueue<MyTestObject>(); queue.Enqueue(new MyTestObject()); Assert.AreEqual(1, queue.Count); object myObject = queue.Dequeue(); Assert.IsInstanceOf(typeof(MyTestObject), myObject); }
public void MemoryQueue_Dequeue_OneItem() { var expected = new LogEntry(); var queue = new MemoryQueue(); queue.Enqueue(expected); var actual = queue.Dequeue(); Assert.AreEqual(0, queue.Count, "Expected zero entries in the queue"); Assert.AreEqual(expected.Id, actual.Id, "The Id of the enqueued item did not match the Id of the dequeued item."); Assert.AreEqual(expected, actual, "A different object was returned from dequeue than what was inserted."); }
public void ShouldDequeueWithTimeSpanTimeout() { int expected = 1000; MemoryQueue<MyTestObject> queue = new MemoryQueue<MyTestObject>(); TimeSpan timespan = new TimeSpan(0, 0, 0, 0, expected); queue.Dequeue(expected); int actual = Convert.ToInt32(timespan.TotalMilliseconds); // We divide to ensure that a millisecond or so won't make a difference to our test result. expected = expected / 100; actual = actual / 100; Assert.AreEqual(expected, actual); }
public void ParallelUnitTest() { ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); var m = new MemoryQueue(); RedisPromiseClient promiseClient = new RedisPromiseClient(redis); int taskCount = 100; ITask[] tasks = new ITask[taskCount]; PromiseTaskResultHandle <int>[] handles = new PromiseTaskResultHandle <int> [taskCount]; for (int i = 0; i < taskCount; i++) { var add = new AddTask(new (i, i + 1)); tasks[i] = add; var handle = new PromiseTaskResultHandle <int>(add, redis); handle.Listen(promiseClient); m.Enqueue(add.Serialize()); handles[i] = handle; } var resolver = new RedisPromiseServer(redis); // this is simulating many workers are resolving promises. (executing tasks in this context) Parallel.ForEach(handles, ((handle) => { var task = new DefaultTaskDeserializer().Deserialize((string)m.Dequeue()); task.Execute(); var res = task.SerializeResult(); // thanks to BindPromise each task's instance id is also id of its related promise. So we can directly resolve related promise by using it. resolver.Resolve(task.GetInstanceIdentifier(), res); })); for (int i = 0; i < taskCount; i++) { int correctResult = i + i + 1; while (!handles[i].IsResolved()) { // it might not come from redis yet Thread.Sleep(10); } var calculatedResult = (int)handles[i].GetObjectResult(); Assert.Equal(correctResult, calculatedResult); } }
public void ShouldDequeueWithIntTimeout() { int expected = 1000; MemoryQueue<MyTestObject> queue = new MemoryQueue<MyTestObject>(); DateTime startDateTime = DateTime.UtcNow; queue.Dequeue(expected); DateTime endDateTime = DateTime.UtcNow; TimeSpan timeSpace = endDateTime - startDateTime; int actual = Convert.ToInt32(timeSpace.TotalMilliseconds); // We divide to ensure that a millisecond or so won't make a difference to our test result. expected = expected / 100; actual = actual / 100; Assert.AreEqual(expected, actual); }
static void TestTaskExecuting() { Console.WriteLine("Hello World!"); var m = new MemoryQueue(); var mult = new MultiplyTask(new Inp { x = 4, y = 5 }); var mult2 = new MultiplyTask(new Inp { x = 4, y = 56 }); var add = new AddTask(new (5, 6)); var swap = new SwapTask(new ("abi", "naber")); var concat = new ConcatTask(new Inp2 { x = new List <string> { "f", "u", "r", "k", "a", "n" } }); var matrix = new Matrix(); matrix.nums = new int[100, 100]; var matrixSum = new MatrixSum(matrix); //TestClient(); m.Enqueue(mult.Serialize()); m.Enqueue(mult2.Serialize()); m.Enqueue(add.Serialize()); m.Enqueue(swap.Serialize()); m.Enqueue(concat.Serialize()); m.Enqueue(matrixSum.Serialize()); // normally these will happen in workers. workers will execute tasks and store their results in // result store. Client will have an TaskResult handle which will update its content when result is ready. // below res1 will be all client have. This program.cs is only for testing purposes normally workers and // client will be different processes. /* Normally it will look like this; * * For Client: * * TaskResult mult=new MultiplyTask(new Inp{x=4,y=5}); this will enqueue task, will get the handle from store(or somewhere else) * TaskResult.result == null => will be true until result is executed by some worker * * For workers: each worker will dequeue from TaskStore and push results to ResultStore like; * * ITask task = queue.Dequeue(); * task.Execute() * resultStore.SetResultOfTask(task); */ Console.WriteLine("tasks queued"); Console.WriteLine("task will be dequed. Now cleaning task registry to simulate a server..."); var registry = (ITaskRegistry)TaskRegistry.Instance; registry.Clear(); registry.DiscoverTasks(); for (long i = m.Length(); i > 0; i--) { string serialized = (string)m.Dequeue(); Console.WriteLine($"dequed task: {serialized}"); var task = new DefaultTaskDeserializer().Deserialize(serialized); Console.WriteLine("task is executing..."); task.Execute(); Console.WriteLine($"time elapsed: {task.GetTimeElapsed().Value.TotalMilliseconds} ms"); } var x = "x"; }
private void ProcessSerialPortData() { byte[] buffer = new byte[1024]; if (_serialPort.BytesToRead == 0) { Thread.Sleep(100); } while (true) { if (_serialPort.BytesToRead == 0) { break; } int bytesRead = _serialPort.Read(buffer, 0, Math.Min(buffer.Length, _serialPort.BytesToRead)); if (!_continue || bytesRead == 0) { break; } _queue.Write(buffer, 0, bytesRead); bool stop = false; while (_queue.Length > _header.Length && !stop) { if (_packetType == null) { byte[] otherData = _queue.DequeueUntil(_header); if (otherData != null && otherData.Length > 0) { OnDataArrived(otherData); } if (!_queue.StartsWith(_header)) { break; } _queue.Dequeue(_header.Length); _packetType = _queue.Dequeue(); } switch (_packetType.Value) { case PT_TELEMETRY: if (_queue.Length >= SIZE_TELEMETRY) { byte[] telemetryBytes = _queue.Dequeue(SIZE_TELEMETRY); _packetType = null; int i = 0; Telemetry telemetry = new Telemetry { Yaw = BinaryHelper.ReadFloat(telemetryBytes, ref i), Pitch = BinaryHelper.ReadFloat(telemetryBytes, ref i), Roll = BinaryHelper.ReadFloat(telemetryBytes, ref i), MotorLeft = BinaryHelper.ReadFloat(telemetryBytes, ref i), MotorRight = BinaryHelper.ReadFloat(telemetryBytes, ref i), MotorFront = BinaryHelper.ReadFloat(telemetryBytes, ref i), MotorBack = BinaryHelper.ReadFloat(telemetryBytes, ref i), BatteryLevel = BinaryHelper.ReadFloat(telemetryBytes, ref i), UserThrottle = BinaryHelper.ReadFloat(telemetryBytes, ref i), UserPitch = BinaryHelper.ReadFloat(telemetryBytes, ref i), UserRoll = BinaryHelper.ReadFloat(telemetryBytes, ref i), UserYaw = BinaryHelper.ReadFloat(telemetryBytes, ref i), LoopCount = BinaryHelper.ReadLong(telemetryBytes, ref i) }; WriteToLog(telemetry.Pitch + "," + telemetry.UserThrottle + "," + telemetry.MotorFront + "," + telemetry.MotorBack); OnTelemetryArrived(telemetry); } else { stop = true; } break; case PT_SETTINGS: if (_queue.Length >= SIZE_SETTINGS) { byte[] pidBytes = _queue.Dequeue(SIZE_SETTINGS); _packetType = null; int i = 0; SettingsPacket settings = new SettingsPacket { PidRoll = new PidObj { P = BinaryHelper.ReadFloat(pidBytes, ref i), I = BinaryHelper.ReadFloat(pidBytes, ref i), D = BinaryHelper.ReadFloat(pidBytes, ref i) }, PidPitch = new PidObj { P = BinaryHelper.ReadFloat(pidBytes, ref i), I = BinaryHelper.ReadFloat(pidBytes, ref i), D = BinaryHelper.ReadFloat(pidBytes, ref i) }, PidYaw = new PidObj { P = BinaryHelper.ReadFloat(pidBytes, ref i), I = BinaryHelper.ReadFloat(pidBytes, ref i), D = BinaryHelper.ReadFloat(pidBytes, ref i) }, Gain = BinaryHelper.ReadFloat(pidBytes, ref i), WindupGuard = BinaryHelper.ReadFloat(pidBytes, ref i) }; OnSettingsArrived(settings); } else { stop = true; } break; case PT_RECV: if (_queue.Length >= SIZE_RECV) { byte[] recvBytes = _queue.Dequeue(SIZE_RECV); _packetType = null; int i = 0; RecieverPacket recvData = new RecieverPacket { Time = BinaryHelper.ReadUnsignedLong(recvBytes, ref i), HasSignal = BinaryHelper.ReadByte(recvBytes, ref i) == 0 ? false : true, }; recvData.Channel[0] = BinaryHelper.ReadFloat(recvBytes, ref i); recvData.Channel[1] = BinaryHelper.ReadFloat(recvBytes, ref i); recvData.Channel[2] = BinaryHelper.ReadFloat(recvBytes, ref i); recvData.Channel[3] = BinaryHelper.ReadFloat(recvBytes, ref i); recvData.Channel[4] = BinaryHelper.ReadFloat(recvBytes, ref i); recvData.Channel[5] = BinaryHelper.ReadFloat(recvBytes, ref i); WriteToLog(recvData.Time + "," + recvData.HasSignal + "," + recvData.Channel[0] + "," + recvData.Channel[1] + "," + recvData.Channel[2] + "," + recvData.Channel[3] + "," + recvData.Channel[4] + "," + recvData.Channel[5]); OnReceiverArrived(recvData); } else { stop = true; } break; case PT_IMU: if (_queue.Length >= SIZE_IMU) { byte[] recvBytes = _queue.Dequeue(SIZE_IMU); _packetType = null; int i = 0; ImuPacket imuData = new ImuPacket { Time = BinaryHelper.ReadUnsignedLong(recvBytes, ref i), AccelRoll = BinaryHelper.ReadFloat(recvBytes, ref i), AccelPitch = BinaryHelper.ReadFloat(recvBytes, ref i), CompassYaw = BinaryHelper.ReadFloat(recvBytes, ref i), Gx = BinaryHelper.ReadFloat(recvBytes, ref i), Gy = BinaryHelper.ReadFloat(recvBytes, ref i), Gz = BinaryHelper.ReadFloat(recvBytes, ref i), Roll = BinaryHelper.ReadFloat(recvBytes, ref i), Pitch = BinaryHelper.ReadFloat(recvBytes, ref i), Yaw = BinaryHelper.ReadFloat(recvBytes, ref i) }; WriteToLog((imuData.Time / 1000000.0).ToString("0.00") + "," + imuData.Gx + "," + imuData.Gy + "," + imuData.Gz + "," + imuData.AccelRoll + "," + imuData.AccelPitch + "," + imuData.CompassYaw + "," + imuData.Roll + "," + imuData.Pitch + "," + imuData.Yaw); OnImuArrived(imuData); } else { stop = true; } break; default: _packetType = null; break; } } } }