// None -> Bonding|Connecting -> Connected -> EnteringBoot -> Updating -> Success internal async Task TryConnect() { lock (_stateLocker) { if (CurrentState != State.None && CurrentState != State.Error) { return; } CurrentState = _isBonded ? State.Connecting : State.Bonding; } try { var res = await _hub.Process <ConnectDeviceResponse>( new ConnectDeviceCommand(_mac), x => x.Mac == _mac); if (res.Device == null) { throw new Exception("Failed to connect device"); } CurrentState = State.Connected; SetDevice(res.Device); await _hub.Publish(new DeviceConnectedEvent(this)); } catch (Exception ex) { CustomError = ex.FlattenMessage(); CurrentState = State.Error; } }
public async Task Test_MultiProcess() { var hub = new MetaPubSub(); Task Handler(MyMessage x) { hub.Publish(new MyEvent() { SomeId = x.SomeId }); return(Task.CompletedTask); } hub.Subscribe <MyMessage>(Handler); var t1 = Task.Run(async() => { for (int i = 0; i < 100; i++) { var message = new MyMessage { SomeId = i, ResponseTimeout = 1000 }; var res = await hub.Process <MyEvent>(message, x => x.SomeId == i); Assert.IsNotNull(res); Assert.IsTrue(res.SomeId == i); } }); var t2 = Task.Run(async() => { for (int i = 100; i < 200; i++) { var message = new MyMessage { SomeId = i, ResponseTimeout = 1000 }; var res = await hub.Process <MyEvent>(message, x => x.SomeId == i); Assert.IsNotNull(res); Assert.IsTrue(res.SomeId == i); } }); await Task.WhenAll(t1, t2); }
public async Task Test_Process() { var hub = new MetaPubSub(); Task Handler(MyMessage x) { hub.Publish(new MyEvent()); return(Task.CompletedTask); } hub.Subscribe <MyMessage>(Handler); var message = new MyMessage { LogSeverity = MetaLogErrorSeverity.Info, DeliverAtLeastOnce = true, Timeout = 100 }; var res = await hub.Process <MyEvent>(message, 100); Assert.IsNotNull(res); }
// request-response pattern - send a message and wait for the response as a single awaitable method, without need to Subscribe/Unsubscribe to the response message public static async Task ProcessExample() { var hub = new MetaPubSub(); // This handler should be placed somewhere in another module. // It processes MyMessage and publishes a MyEvent as a result. Task Handler(MyMessage x) { hub.Publish(new MyEvent()); return(Task.CompletedTask); } hub.Subscribe <MyMessage>(Handler); try { // This method will publish MyMessage and wait for MyEvent one second. // If the event will not arrive in a specified timeout the TimeoutException will be thrown. var message = new MyMessage { DeliverAtLeastOnce = true, WaitForSubscriberTimeout = 100, ResponseTimeout = 1_000 }; MyEvent res = await hub.Process <MyEvent>(message); Console.WriteLine($"Received MyEvent at {DateTime.Now:HH:mm:ss.fff}"); } catch (NoSubscribersException ex) { // no one is listening Console.WriteLine($"Exception {ex.GetType()}: {ex.Message}"); } catch (TimeoutException ex) { Console.WriteLine($"Exception {ex.GetType()}: {ex.Message}"); } }
public async Task Test_Process() { var hub = new MetaPubSub(); Task Handler(MyMessage x) { Task.Run(async() => { await Task.Delay(10); await hub.Publish(new MyEvent()); }); return(Task.CompletedTask); } hub.Subscribe <MyMessage>(Handler); var message = new MyMessage { ResponseTimeout = 2000 }; var res = await hub.Process <MyEvent>(message); Assert.IsNotNull(res); }