void IDataStore.Save(OutgoingSmsMessage msg) { if (!OutgoingMessages.Any(m => m.Id == msg.Id)) { OutgoingMessages.Add(msg); } SaveChanges(); }
void IDataStore.ScheduleMessage(OutgoingSmsMessage msg, Subscription sub) { OutgoingMessages.Add(msg); Subscription toUpdate = Subscriptions.Where(s => s.Id == sub.Id).FirstOrDefault(); if (toUpdate != null) { toUpdate.Next = DateTime.Today.AddDays(1).AddHours(4).ToUniversalTime(); } SaveChanges(); }
void IDataStore.Remove(OutgoingSmsMessage message) { if (message != null) { foreach (OutgoingSmsMessage msg in OutgoingMessages.Where(m => m.Id == message.Id)) { OutgoingMessages.Remove(msg); } SaveChanges(); } }
public void SenderFailsCallback() { ObjectFactory.Initialize(x => { x.For<ILogging>().Use<TraceLogger>(); x.For<ISmsTransport>().Use<FailureSmsSender>(); x.For<IDataStore>().Use<TestDataStore>(); }); int toSend = 10; int[] count = { 0 }; ManualResetEvent done = new ManualResetEvent(false); bool[] sendSucceeded = new[] { false }; SendCompleteCallback complete = (SentSmsMessageLogEntry result, OutgoingSmsMessage msg) => { sendSucceeded[0] = result.Status != (int)MessageSendStatus.Error; Assert.AreEqual(count[0], msg.Id, "The subscription ID was incorrect"); Assert.AreEqual((int)MessageSendStatus.Error, result.Status); count[0]++; if (count[0] == toSend) { done.Set(); } }; SmsSenderExceptionThrownCallback failed = (OutgoingSmsMessage msg, Exception exception) => { Assert.Fail("The exception callback should not have been called"); }; SmsSenderQueue sender = new SmsSenderQueue(); for (int i = 0; i < 10; i++) { OutgoingSmsMessage msg = new OutgoingSmsMessage { Message = "This is the message", Destination = "+11234567890", Id = i, }; sender.Send(msg, complete, failed); } Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(toSend)), "Sending timed out ... that's not good!"); Assert.IsFalse(sendSucceeded[0], "The send should not have been marked as successful"); }
void MessageSent(SentSmsMessageLogEntry result, OutgoingSmsMessage message) { IDataStore store = DataStore.GetInstance(); if (result.Status == (int)MessageSendStatus.Success) { // delete copy local to this store store.Remove(store.OutgoingMessages.Where(m => m.Id == message.Id).FirstOrDefault()); } else { ProcessSendFailure(message); } }
public void Send(OutgoingSmsMessage msg, SendCompleteCallback complete, SmsSenderExceptionThrownCallback exceptionThrown) { ThrowIfDisposed(); lock (_lock) { if (!queued.Contains(msg.Id)) { _processor.Add(new SmsSenderMessage { Message = msg, Complete = complete, Failed = exceptionThrown, }); queued.Add(msg.Id); } } }
public void SenderSends() { ObjectFactory.Initialize(x => { x.For<ILogging>().Use<TraceLogger>(); x.For<ISmsTransport>().Use<SuccessSmsSender>(); x.For<IDataStore>().Use<TestDataStore>(); }); int toSend = 10; int[] count = { 0 }; ManualResetEvent done = new ManualResetEvent(false); bool[] sendFailed = new bool[1] { false }; SendCompleteCallback complete = (SentSmsMessageLogEntry result, OutgoingSmsMessage msg) => { Assert.AreEqual((int)MessageSendStatus.Success, result.Status); Assert.AreEqual(count[0], msg.Id, "The subscription ID was incorrect"); count[0]++; if (count[0] == toSend) { done.Set(); } }; SmsSenderExceptionThrownCallback failed = (OutgoingSmsMessage message, Exception exception) => { sendFailed[0] = true; Assert.Fail(string.Format(CultureInfo.InvariantCulture, "Sending message {0} failed?", message.Id)); }; SmsSenderQueue sender = new SmsSenderQueue(); for (int i = 0; i < 10; i++) { OutgoingSmsMessage msg = new OutgoingSmsMessage { Message = "This is the message", Destination = "+11234567890", Id = i, }; sender.Send(msg, complete, failed); } Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(toSend)), "Sending timed out ... that's not good!"); Assert.IsFalse(sendFailed[0], "The send was marked as failed ... wtf???"); }
public void ScheduleMessage(OutgoingSmsMessage msg, Subscription sub) { lock (_lock) { Save(msg); Subscription toUpdate = Subscriptions.Where(s => s.Id == sub.Id).FirstOrDefault(); if (toUpdate != null) { toUpdate.Next = DateTime.Today.AddDays(1).ToUniversalTime().AddHours(2); } } }
public void Save(OutgoingSmsMessage msg) { lock (_lock) { if (msg.Id == 0) { msg.Id = NextId(); } _outgoingMessages[msg.Id] = msg; } }
public void Remove(OutgoingSmsMessage msg) { lock (_lock) { _outgoingMessages.Remove(msg.Id); } }
void MessageSendThrewException(OutgoingSmsMessage msg, Exception ex) { LogManager.Log.Error("Exception sending SMS message", ex); ProcessSendFailure(msg); }
private void ProcessSendFailure(OutgoingSmsMessage msg) { IDataStore store = DataStore.GetInstance(); // reload from the local store msg = store.OutgoingMessages.Where(m => m.Id == msg.Id).First(); if (msg != null) { if (msg.Attempts < 10) { msg.Attempts++; DateTime next; if (msg.Attempts < 10) { next = DateTime.UtcNow.AddMinutes(msg.Attempts * 10); } else { next = DateTime.UtcNow.AddHours(18); } msg.NextAttempt = next; store.Save(msg); } else { SentSmsMessageLogEntry entry = new SentSmsMessageLogEntry { Date = DateTime.UtcNow, Destination = msg.Destination, Message = msg.Message, Status = (int)MessageSendStatus.Abandoned, Details = string.Format(CultureInfo.InvariantCulture, "Fatal SMS Send error - giving up on sending message {0} - it was attempted {1} times.", msg.Id, msg.Attempts), }; store.Save(entry); store.Remove(msg); } } }