private async Task Broadcast(SubscriptionTrackingDatagram datagram)
        {
            try
            {
                var bytes    = datagram.Encode();
                var endpoint = new IPEndPoint(_groupAddress, _port);
                await _broadcastClient.SendAsync(bytes, bytes.Length, endpoint);

                await _diagnosticService.EmitAsync(new MulticastEventBuilder(this, MulticastEventType.DatagramBroadcast)
                {
                    Node = _nodeId.ToString(),
                    Host = _groupAddress.ToString(),
                    Port = _port
                }.Build());
            }
            catch (Exception e)
            {
                _diagnosticService.Emit(new MulticastEventBuilder(this, MulticastEventType.DatagramBroadcastError)
                {
                    Detail    = "Error broadcasting datagram",
                    Node      = _nodeId.ToString(),
                    Host      = _groupAddress.ToString(),
                    Port      = _port,
                    Exception = e
                }.Build());
            }
        }
        /// <inheritdoc />
        public async Task RemoveSubscription(TopicName topic, Uri subscriber, CancellationToken cancellationToken = new CancellationToken())
        {
            CheckDisposed();
            await _inner.RemoveSubscription(topic, subscriber, cancellationToken);

            var datagram = new SubscriptionTrackingDatagram(_nodeId,
                                                            SubscriptionTrackingDatagram.ActionType.Remove, topic, subscriber);

            await Broadcast(datagram);
        }
        /// <inheritdoc />
        public async Task AddSubscription(TopicName topic, Uri subscriber, TimeSpan ttl = new TimeSpan(),
                                          CancellationToken cancellationToken           = new CancellationToken())
        {
            CheckDisposed();
            await _inner.AddSubscription(topic, subscriber, ttl, cancellationToken);

            var datagram = new SubscriptionTrackingDatagram(_nodeId,
                                                            SubscriptionTrackingDatagram.ActionType.Add, topic, subscriber, ttl);

            await Broadcast(datagram);
        }
        private async Task HandleReceiveResult(UdpReceiveResult result)
        {
            try
            {
                var datagram = SubscriptionTrackingDatagram.Decode(result.Buffer);
                if (datagram.NodeId == _nodeId)
                {
                    return;
                }

                switch (datagram.Action)
                {
                case SubscriptionTrackingDatagram.ActionType.Add:
                    await _inner.AddSubscription(datagram.Topic, datagram.SubscriberUri, datagram.TTL);

                    return;

                case SubscriptionTrackingDatagram.ActionType.Remove:
                    await _inner.RemoveSubscription(datagram.Topic, datagram.SubscriberUri);

                    return;

                default:
                    await _diagnosticService.EmitAsync(new MulticastEventBuilder(this, MulticastEventType.MalformedDatagram)
                    {
                        Detail = "Unknown or unsupported subscription tracking action: " + datagram.Action,
                        Node   = _nodeId.ToString(),
                        Host   = result.RemoteEndPoint.Address.ToString(),
                        Port   = result.RemoteEndPoint.Port
                    }.Build());

                    break;
                }
            }
            catch (Exception e)
            {
                _diagnosticService.Emit(new MulticastEventBuilder(this, MulticastEventType.MalformedDatagram)
                {
                    Detail    = "Error unmarshaling datagram",
                    Node      = _nodeId.ToString(),
                    Host      = result.RemoteEndPoint.Address.ToString(),
                    Port      = result.RemoteEndPoint.Port,
                    Exception = e
                }.Build());
            }
        }