Example #1
0
        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());
                    }
                }
            }
        }
Example #3
0
        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();
                    }
                }
            }
        }
Example #5
0
        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();
                    }
                }
            }
        }