/// <summary>
        /// Send the message created with <paramref name="deliveryMessageMapper"/> function to the <see cref="destination"/>
        /// actor. It will retry sending the message until the delivery is confirmed with <see cref="ConfirmDelivery"/>.
        /// Correlation between these two methods is performed by delivery id - parameter of <see cref="deliveryMessageMapper"/>.
        /// Usually it's passed inside the message to the destination, which replies with the message having the same id.
        /// 
        /// During recovery this method won't send out any message, but it will be sent later until corresponding 
        /// <see cref="ConfirmDelivery"/> method will be invoked.
        /// </summary>
        /// <exception cref="MaxUnconfirmedMessagesExceededException">
        /// Thrown when <see cref="UnconfirmedCount"/> is greater than or equal to <see cref="MaxUnconfirmedMessages"/>.
        /// </exception>
        public void Deliver(ActorPath destination, Func<long, object> deliveryMessageMapper)
        {
            if (UnconfirmedCount >= MaxUnconfirmedMessages)
            {
                throw new MaxUnconfirmedMessagesExceededException(string.Format("{0} has too many unconfirmed messages. Maximum allowed is {1}", PersistenceId, MaxUnconfirmedMessages));
            }

            var deliveryId = NextDeliverySequenceNr();
            var now = IsRecovering ? DateTime.Now - RedeliverInterval : DateTime.Now;
            var delivery = new Delivery(destination, deliveryMessageMapper(deliveryId), now, attempt: 0);

            if (IsRecovering)
            {
                _unconfirmed.AddOrUpdate(deliveryId, delivery, (id, d) => delivery);
            }
            else
            {
                Send(deliveryId, delivery, now);
            }
        }
        private void Send(long deliveryId, Delivery delivery, DateTime timestamp)
        {
            var destination = Context.ActorSelection(delivery.Destination);
            destination.Tell(delivery.Message);

            var dcopy = new Delivery(delivery.Destination, delivery.Message, timestamp, delivery.Attempt + 1);
            _unconfirmed.AddOrUpdate(deliveryId, dcopy, (id, d) => dcopy);
        }
Esempio n. 3
0
 private void Send(long deliveryId, Delivery delivery, DateTime timestamp)
 {
     _context.ActorSelection(delivery.Destination).Tell(delivery.Message);
     _unconfirmed = _unconfirmed.SetItem(deliveryId, new Delivery(delivery.Destination, delivery.Message, timestamp, delivery.Attempt + 1));
     StartRedeliverTask();
 }