protected override void DistributeMSMQ(KissTransactionMode mode, bool remove, string[] filter, LargeMessage largeMessage) { List <MessageQueue> allQueues = null; MessageQueueTransaction msmqTransaction = null; var ttrqPo = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.PO_TTRQ)); var ttbrPo = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.PO_TTBR)); try { largeMessage.EncodeExtension(new[] { _id, DateTime.Now.ToBinary().ToString(), remove.ToString() }); allQueues = new Neighborhood(_sql, FORMAT_PO_POSTFIX).GetAllQueues(filter); if (allQueues.Count > 0) { if (mode == KissTransactionMode.MSMQ) { msmqTransaction = new MessageQueueTransaction(); msmqTransaction.Begin(); } foreach (var queue in allQueues) { largeMessage.Send(queue, msmqTransaction, ttrqPo, ttbrPo); } if (mode == KissTransactionMode.MSMQ) { msmqTransaction.Commit(); } } } catch { if (msmqTransaction != null && mode == KissTransactionMode.MSMQ) { msmqTransaction.Abort(); } throw; } finally { if (msmqTransaction != null) { msmqTransaction.Dispose(); } if (allQueues != null) { foreach (var queue in allQueues) { queue.Dispose(); } } } }
public void ProcessInstructions(KissTransactionMode mode) { string path, branchId; byte[] sdData; XPathNavigator instruction; StandingData standingData; var filter = new List <string>(); var neighborhood = new Neighborhood(_sql); var neighborhoodClients = neighborhood.GetAllClients().ToArray(); foreach (var id in StandingData.RetrieveInstructionAll(_sql)) { using (var sr = new StringReader(StandingData.RetrieveInstruction(_sql, long.Parse(id)))) { instruction = new XPathDocument(sr).CreateNavigator(); path = instruction.SelectSingleNode("//StandingData/@Path").Value; branchId = instruction.SelectSingleNode("//StandingData/@BranchId").Value; Array.Sort(neighborhoodClients); foreach (XPathNavigator clientId in instruction.Select("//Client/@Id")) { if (Array.BinarySearch(neighborhoodClients, clientId.Value) >= 0) { filter.Add(clientId.Value); } } if (branchId == neighborhood.GetLocalBranch() && filter.Count > 0) { sdData = DownloadStandingData(path); standingData = new StandingData(_sql, long.Parse(id), _msmqCapacity, sdData); standingData.Distribute(mode, filter.ToArray()); } } } }
public void RecoverBundles() { long id, maxId = ID_NOT_RECEIVED_AT_BACKEND; bool responseAvailable, localRecoveryDone, remoteRecoveryDone; DateTime?selfLastUpdate; MessageQueue[] controlQueuesOpen, controlQueues = null; MessageQueue recoveryQueue = null; var ttrqBundleControl = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.BUNDLE_CONTROL_TTRQ)); var ttbrBundleControl = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.BUNDLE_CONTROL_TTBR)); try { controlQueues = new Neighborhood(_sql, FORMAT_BUNDLE_CONTROL_POSTFIX).GetOthersQueues().ToArray(); controlQueuesOpen = new MessageQueue[controlQueues.Length]; controlQueues.CopyTo(controlQueuesOpen, 0); recoveryQueue = new Neighborhood(_sql, FORMAT_BUNDLE_RECOVERY_POSTFIX).GetLocalQueue(); localRecoveryDone = !(controlQueues.Length > 0); while (!localRecoveryDone) { for (var i = 0; i < controlQueues.Length; i++) { if (controlQueuesOpen[i] == null) { continue; } using (var msg = new Message(_clientId) { ResponseQueue = recoveryQueue, Formatter = controlQueues[i].Formatter, TimeToReachQueue = ttrqBundleControl, TimeToBeReceived = ttbrBundleControl, Extension = LargeMessage.ToMessageExtension(Guid.NewGuid()) }) { responseAvailable = false; controlQueues[i].Send(msg, MessageQueueTransactionType.Single); for (var j = 0; j < MAX_RETRY_BUNDLE_RECOVERY && !responseAvailable; j++) { Thread.Sleep(SLEEP_BUNDLE_RECOVERY); responseAvailable = LargeMessage.IsCorrelationAvailable(recoveryQueue, msg.Id); } if (responseAvailable) { using (var response = recoveryQueue. ReceiveByCorrelationId(msg.Id, MessageQueueTransactionType.Single)) { id = (long)response.Body; if (id > maxId) { maxId = id; } } controlQueuesOpen[i] = null; } } } localRecoveryDone = Array.TrueForAll(controlQueuesOpen, q => q == null); } RemoveAllBundlesAndStages(); do { QueryStageList(true); WaitForSelfStage(true, null, out id, out selfLastUpdate); remoteRecoveryDone = id != ID_NO_ANSWER_FROM_BACKEND; if (!remoteRecoveryDone) { Thread.Sleep(SLEEP_BUNDLE_RECOVERY); } } while (!remoteRecoveryDone); if (id > maxId) { maxId = id; } if (maxId != ID_NOT_RECEIVED_AT_BACKEND) { new Bundle(_sql, maxId, _clientId, _msmqCapacity).Recover(); } } finally { if (recoveryQueue != null) { recoveryQueue.Dispose(); } if (controlQueues != null) { foreach (var queue in controlQueues) { queue.Dispose(); } } } }
public void RecoverPersistentObjects() { bool localRecoveryDone; List <MessageQueue> controlQueues = null; MessageQueue recoveryQueue = null; var poListener = new PersistentObjectListener(_sql, _msmqCapacity); var ttrqPoControl = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.PO_CONTROL_TTRQ)); var ttbrPoControl = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.PO_CONTROL_TTBR)); try { controlQueues = new Neighborhood(_sql, FORMAT_PO_CONTROL_POSTFIX).GetOthersQueues(); recoveryQueue = new Neighborhood(_sql, FORMAT_PO_RECOVERY_POSTFIX).GetLocalQueue(); localRecoveryDone = !(controlQueues.Count > 0); if (localRecoveryDone) { poListener.Recover(recoveryQueue, string.Empty); } while (!localRecoveryDone) { foreach (var controlQueue in controlQueues) { using (var msg = new Message { ResponseQueue = recoveryQueue, Formatter = controlQueue.Formatter, TimeToReachQueue = ttrqPoControl, TimeToBeReceived = ttbrPoControl, Extension = LargeMessage.ToMessageExtension(Guid.NewGuid()) }) { controlQueue.Send(msg, MessageQueueTransactionType.Single); for (var i = 0; i < MAX_RETRY_PO_RECOVERY && !localRecoveryDone; i++) { Thread.Sleep(SLEEP_PO_RECOVERY); localRecoveryDone = LargeMessage.IsCorrelationAvailable(recoveryQueue, msg.Id); } if (localRecoveryDone) { poListener.Recover(recoveryQueue, msg.Id); break; } } } } } finally { if (recoveryQueue != null) { recoveryQueue.Dispose(); } if (controlQueues != null) { foreach (var queue in controlQueues) { queue.Dispose(); } } } }
protected override void DistributeMSMQ(KissTransactionMode mode, bool remove, string[] filter, LargeMessage largeMessage) { object sequenceNumber; string bundleSentChar; DateTime bundleSent; MessageQueueTransaction msmqTransaction = null; List <MessageQueue> othersQueues = null; var ttrqBundle = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.BUNDLE_TTRQ)); var ttbrBundle = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.BUNDLE_TTBR)); var dialogLifetime = Kiss.GetTimeout(KissTimeout.BUNDLE_SSSB); var dtctoBundle = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.BUNDLE_DTC_DISTRIBUTION)); if (remove) { throw new NotSupportedException("remove"); } try { othersQueues = new Neighborhood(_sql, FORMAT_BUNDLE_POSTFIX).GetOthersQueues(filter); using (var scope = new TransactionScope(TransactionScopeOption.Required, dtctoBundle)) { bundleSent = DateTime.Now; bundleSentChar = bundleSent.ToString(FORMAT_BUNDLE_SENT, DateTimeFormatInfo.InvariantInfo); Process(PROCEDURE_BUNDLE_PROCESSING, new[] { new SqlParameter("@client_id", _clientId), new SqlParameter("@bundle_sent", bundleSent), new SqlParameter("@bundle_sent_char", bundleSentChar), new SqlParameter("@dialog_lifetime", dialogLifetime) }, "@bundle", out sequenceNumber); largeMessage.EncodeExtension(new[] { sequenceNumber.ToString(), _clientId, bundleSent.ToBinary().ToString() }); if (mode == KissTransactionMode.DTC) { foreach (var queue in othersQueues) { largeMessage.Send(queue, null, ttrqBundle, ttbrBundle); } } else { using (var suppress = new TransactionScope(TransactionScopeOption.Suppress)) { msmqTransaction = new MessageQueueTransaction(); msmqTransaction.Begin(); foreach (var queue in othersQueues) { largeMessage.Send(queue, msmqTransaction, ttrqBundle, ttbrBundle); } suppress.Complete(); } } scope.Complete(); } _id = (long)sequenceNumber; SetOutputHeader(string.Format(FORMAT_TO_STRING, _id, _clientId)); if (mode != KissTransactionMode.DTC) { msmqTransaction.Commit(); } } catch { if (msmqTransaction != null && mode == KissTransactionMode.MSMQ) { msmqTransaction.Abort(); } throw; } finally { if (msmqTransaction != null) { msmqTransaction.Dispose(); } if (othersQueues != null) { foreach (var queue in othersQueues) { queue.Dispose(); } } } }