protected static string[] RetrieveAll(string sql, string catalogView, RowProjection FormatRow)
        {
            string[] result;
            var      sqltoDistr = Kiss.GetTimeout(KissTimeout.DISTRIBUTION_SQL_RETRIEVE_ALL);

            using (var scope = new TransactionScope(TransactionScopeOption.Suppress))
                using (var kiss = new SqlConnection(Kiss.GetConnection(sql)))
                    using (var allIds = new SqlCommand(catalogView, kiss)
                    {
                        CommandTimeout = sqltoDistr,
                        CommandType = CommandType.Text
                    })
                    {
                        kiss.Open();

                        using (var idsTable = new DataTable())
                            using (var idsAdapter = new SqlDataAdapter(allIds))
                            {
                                idsAdapter.Fill(idsTable);
                                result = new string[idsTable.Rows.Count];

                                for (var i = 0; i < idsTable.Rows.Count; i++)
                                {
                                    result[i] = FormatRow(idsTable.Rows[i]);
                                }
                            }

                        kiss.Close();
                        scope.Complete();
                    }

            return(result);
        }
        protected override void OnProcessMessage(KissTransactionMode mode, MessageQueue queue, Guid conversation)
        {
            long id,
                 maxId = ID_NO_VALUE;
            string clientId,
                   recoveryClient;
            Message bundleControl;
            MessageQueueTransaction transaction = null;
            var convMessages = LargeMessage.GetMessagesOfConversation(queue, conversation);
            var allBundleIds = Bundle.RetrieveAll(_sql);
            var ttrqBundle   = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.BUNDLE_TTRQ));
            var ttbrBundle   = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.BUNDLE_TTBR));
            var timeout      = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.BUNDLE_CONTROL_RECEIVE_TIMEOUT));

            if (mode == KissTransactionMode.DTC)
            {
                throw new NotSupportedException("DTC");
            }

            try
            {
                transaction = new MessageQueueTransaction();
                transaction.Begin();

                bundleControl  = queue.ReceiveById(convMessages[0], timeout, transaction);
                recoveryClient = (string)bundleControl.Body;

                foreach (var bundleId in allBundleIds)
                {
                    id       = long.Parse(bundleId.Split(SEPARATOR_BUNDLE_IDS)[0]);
                    clientId = bundleId.Split(SEPARATOR_BUNDLE_IDS)[1];

                    if (clientId == recoveryClient && id > maxId)
                    {
                        maxId = id;
                    }
                }

                using (var msg = new Message(maxId)
                {
                    CorrelationId = bundleControl.Id,
                    Formatter = bundleControl.Formatter,
                    TimeToReachQueue = ttrqBundle,
                    TimeToBeReceived = ttbrBundle,
                    Extension = LargeMessage.ToMessageExtension(Guid.NewGuid())
                })
                {
                    bundleControl.ResponseQueue.Send(msg, transaction);
                }

                transaction.Commit();
            }
            finally
            {
                if (transaction != null)
                {
                    transaction.Dispose();
                }
            }
        }
Beispiel #3
0
        public bool TransmitBundles()
        {
            bool     transmitted;
            long     selfId;
            DateTime?selfLastUpdate,
                    initialLastUpdate;
            var dialogLifetime = Kiss.GetTimeout(KissTimeout.BUNDLE_SSSB);
            var sqltoBundle    = Kiss.GetTimeout(KissTimeout.KISS_SQL_STAGELIST);

            WaitForSelfStage(false, null, out selfId, out initialLastUpdate);
            QueryStageList(false);
            transmitted = WaitForSelfStage(true, initialLastUpdate, out selfId, out selfLastUpdate);

            if (transmitted)
            {
                GarbageCollectBundles();

                using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                    using (var bundleTransmission =
                               new SqlCommand(PROCEDURE_BUNDLE_TRANSMISSION, kiss)
                    {
                        CommandTimeout = sqltoBundle, CommandType = CommandType.StoredProcedure
                    })
                    {
                        bundleTransmission.Parameters.AddWithValue("@dialog_lifetime", dialogLifetime);

                        kiss.Open();
                        bundleTransmission.ExecuteNonQuery();
                        kiss.Close();
                    }
            }

            return(transmitted);
        }
Beispiel #4
0
        private void RemoveAllBundlesAndStages()
        {
            var dtctoBundle = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.BUNDLE_DTC_RECOVERY));
            var sqltoBundle = Kiss.GetTimeout(KissTimeout.BUNDLE_SQL_RECOVERY);

            using (var scope = new TransactionScope(TransactionScopeOption.Required, dtctoBundle))
                using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                    using (var bundleRemoval =
                               new SqlCommand(PROCEDURE_BUNDLE_REMOVAL_ALL, kiss)
                    {
                        CommandTimeout = sqltoBundle,
                        CommandType = CommandType.StoredProcedure
                    })
                        using (var stageRemoval =
                                   new SqlCommand(PROCEDURE_STAGE_REMOVAL_ALL, kiss)
                        {
                            CommandTimeout = sqltoBundle,
                            CommandType = CommandType.StoredProcedure
                        })
                        {
                            kiss.Open();
                            bundleRemoval.ExecuteNonQuery();
                            stageRemoval.ExecuteNonQuery();
                            kiss.Close();

                            scope.Complete();
                        }
        }
        public static object Retrieve(string sql, string retrieveProcedure,
                                      SqlParameter[] retrieveParameters, string dataName)
        {
            object retrieveResult = null;
            var    sqltoDistr     = Kiss.GetTimeout(KissTimeout.DISTRIBUTION_SQL_PROCESS);

            using (var scope = new TransactionScope(TransactionScopeOption.Suppress))
                using (var kiss = new SqlConnection(Kiss.GetConnection(sql)))
                    using (var retrieve =
                               new SqlCommand(retrieveProcedure, kiss)
                    {
                        CommandTimeout = sqltoDistr,
                        CommandType = CommandType.StoredProcedure
                    })
                    {
                        retrieve.Parameters.AddRange(retrieveParameters);

                        kiss.Open();

                        using (var dataReader = retrieve.ExecuteReader(CommandBehavior.SingleRow))
                        {
                            if (dataReader.HasRows)
                            {
                                dataReader.Read();
                                retrieveResult = dataReader[dataName];
                            }
                        }

                        kiss.Close();
                        scope.Complete();
                    }

            return(retrieveResult);
        }
Beispiel #6
0
        public void Recover(MessageQueue recoveryQueue, string correlationId)
        {
            var conversations = LargeMessage.GetConversationsOfCorrelation(recoveryQueue, correlationId);
            var dtctoPo       = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.PO_DTC_RECOVERY));
            var sqltoPo       = Kiss.GetTimeout(KissTimeout.PO_SQL_RECOVERY);

            using (var scope = new TransactionScope(TransactionScopeOption.Required, dtctoPo))
                using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                    using (var poRemoval =
                               new SqlCommand(PROCEDURE_PO_REMOVAL_ALL, kiss)
                    {
                        CommandTimeout = sqltoPo,
                        CommandType = CommandType.StoredProcedure
                    })
                    {
                        kiss.Open();
                        poRemoval.ExecuteNonQuery();
                        kiss.Close();

                        foreach (var conversation in conversations)
                        {
                            OnProcessMessage(KissTransactionMode.DTC, recoveryQueue, conversation);
                        }

                        scope.Complete();
                    }
        }
Beispiel #7
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();
                    }
                }
            }
        }
Beispiel #8
0
        public void Respond(MessageQueue responseQueue, MessageQueueTransaction transaction, string correlationId)
        {
            var largeMessage = new LargeMessage(DataBuffer, null, _msmqCapacity, correlationId, null);
            var ttrqPo       = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.PO_TTRQ));
            var ttbrPo       = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.PO_TTBR));

            largeMessage.EncodeExtension(new[] { _id, DateTime.Now.ToBinary().ToString(), false.ToString() });
            largeMessage.Send(responseQueue, transaction, ttrqPo, ttbrPo);
        }
Beispiel #9
0
        public void GarbageCollectBundles()
        {
            var sqltoBundle = Kiss.GetTimeout(KissTimeout.KISS_SQL_GARBAGE_COLLECTION);

            using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                using (var garbageCollectionExecution =
                           new SqlCommand(PROCEDURE_GARBAGE_COLLECTION, kiss)
                {
                    CommandTimeout = sqltoBundle,
                    CommandType = CommandType.StoredProcedure
                })
                {
                    kiss.Open();
                    garbageCollectionExecution.ExecuteNonQuery();
                    kiss.Close();
                }
        }
Beispiel #10
0
        public void Ping()
        {
            var dialogLifetime = Kiss.GetTimeout(KissTimeout.KISS_SSSB_PING);
            var sqltoPing      = Kiss.GetTimeout(KissTimeout.KISS_SQL_PING);

            using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                using (var ping = new SqlCommand(PROCEDURE_PING, kiss)
                {
                    CommandTimeout = sqltoPing,
                    CommandType = CommandType.StoredProcedure
                })
                {
                    ping.Parameters.AddWithValue("@dialog_lifetime", dialogLifetime);

                    kiss.Open();
                    ping.ExecuteNonQuery();
                    kiss.Close();
                }
        }
Beispiel #11
0
        private void QueryStageList(bool self)
        {
            var dialogLifetime = Kiss.GetTimeout(KissTimeout.KISS_SSSB_STAGELIST);
            var sqltoBundle    = Kiss.GetTimeout(KissTimeout.KISS_SQL_STAGELIST);

            using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                using (var stageListQuerying =
                           new SqlCommand(PROCEDURE_STAGE_LIST_QUERYING, kiss)
                {
                    CommandTimeout = sqltoBundle, CommandType = CommandType.StoredProcedure
                })
                {
                    stageListQuerying.Parameters.AddWithValue("@self", self ? 1 : 0);
                    stageListQuerying.Parameters.AddWithValue("@dialog_lifetime", dialogLifetime);

                    kiss.Open();
                    stageListQuerying.ExecuteNonQuery();
                    kiss.Close();
                }
        }
Beispiel #12
0
        public void Recover()
        {
            var sqltoBundle = Kiss.GetTimeout(KissTimeout.BUNDLE_SQL_RECOVERY);

            using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                using (var bundleRecovery =
                           new SqlCommand(PROCEDURE_BUNDLE_RECOVERY, kiss)
                {
                    CommandTimeout = sqltoBundle,
                    CommandType = CommandType.StoredProcedure
                })
                {
                    bundleRecovery.Parameters.AddWithValue("@bundle_id", _id);
                    bundleRecovery.Parameters.AddWithValue("@client_id", _clientId);

                    kiss.Open();
                    bundleRecovery.ExecuteNonQuery();
                    kiss.Close();
                }
        }
        protected void Process(string processProcedure, SqlParameter[] processParameters,
                               string dataName, out object scalarResult)
        {
            var sqltoDistr = Kiss.GetTimeout(KissTimeout.DISTRIBUTION_SQL_PROCESS);

            using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                using (var process =
                           new SqlCommand(processProcedure, kiss)
                {
                    CommandTimeout = sqltoDistr,
                    CommandType = CommandType.StoredProcedure
                })
                {
                    process.Parameters.AddRange(processParameters);
                    process.Parameters.AddWithValue(dataName, _largeMessage.DataBuffer);

                    kiss.Open();
                    scalarResult = process.ExecuteScalar();
                    kiss.Close();
                }
        }
Beispiel #14
0
        public void RegisterPC(bool deregister)
        {
            var dialogLifetime    = Kiss.GetTimeout(KissTimeout.KISS_SSSB_PC_REGISTRATION);
            var sqltoRegistration = Kiss.GetTimeout(KissTimeout.KISS_SQL_PC_REGISTRATION);

            using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                using (var pcRegistration =
                           new SqlCommand(PROCEDURE_PC_REGISTRATION, kiss)
                {
                    CommandTimeout = sqltoRegistration,
                    CommandType = CommandType.StoredProcedure
                })
                {
                    pcRegistration.Parameters.AddWithValue("@deregister", deregister ? 1 : 0);
                    pcRegistration.Parameters.AddWithValue("@dialog_lifetime", dialogLifetime);

                    kiss.Open();
                    pcRegistration.ExecuteNonQuery();
                    kiss.Close();
                }
        }
        protected override void OnProcessMessage(KissTransactionMode mode, MessageQueue queue, Guid conversation)
        {
            Message                 poControl;
            PersistentObject        po;
            MessageQueueTransaction transaction = null;
            var convMessages = LargeMessage.GetMessagesOfConversation(queue, conversation);
            var allPoIds     = PersistentObject.RetrieveAll(_sql);
            var timeout      = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.PO_CONTROL_RECEIVE_TIMEOUT));

            if (mode == KissTransactionMode.DTC)
            {
                throw new NotSupportedException("DTC");
            }

            try
            {
                transaction = new MessageQueueTransaction();
                transaction.Begin();

                poControl = queue.ReceiveById(convMessages[0], timeout, transaction);

                foreach (var poId in allPoIds)
                {
                    po = new PersistentObject(_sql, poId, _msmqCapacity);
                    po.Retrieve();
                    po.Respond(poControl.ResponseQueue, transaction, poControl.Id);
                }

                transaction.Commit();
            }
            finally
            {
                if (transaction != null)
                {
                    transaction.Dispose();
                }
            }
        }
Beispiel #16
0
        protected override void OnProcessMessage(KissTransactionMode mode, MessageQueue queue, Guid conversation)
        {
            string[] extension;
            MessageQueueTransaction msmqTransaction = null;
            var convMessages = LargeMessage.GetMessagesOfConversation(queue, conversation);
            var largeMessage = new LargeMessage(_msmqCapacity, null);
            var dtctoPo      = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.PO_DTC_STORAGE));
            var sqltoPo      = Kiss.GetTimeout(KissTimeout.PO_SQL_STORAGE);

            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, dtctoPo))
                    using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                        using (var poStorage =
                                   new SqlCommand(PROCEDURE_PO_STORAGE, kiss)
                        {
                            CommandTimeout = sqltoPo,
                            CommandType = CommandType.StoredProcedure
                        })
                            using (var poRemoval =
                                       new SqlCommand(PROCEDURE_PO_REMOVAL, kiss)
                            {
                                CommandTimeout = sqltoPo,
                                CommandType = CommandType.StoredProcedure
                            })
                            {
                                if (mode == KissTransactionMode.DTC)
                                {
                                    largeMessage.Receive(queue, null, convMessages,
                                                         Kiss.GetTimeout(KissTimeout.PO_RECEIVE_TIMEOUT));
                                }
                                else
                                {
                                    using (var suppress = new TransactionScope(TransactionScopeOption.Suppress))
                                    {
                                        msmqTransaction = new MessageQueueTransaction();
                                        msmqTransaction.Begin();

                                        largeMessage.Receive(queue, msmqTransaction, convMessages,
                                                             Kiss.GetTimeout(KissTimeout.PO_RECEIVE_TIMEOUT));

                                        suppress.Complete();
                                    }
                                }

                                extension = largeMessage.DecodeExtension();
                                kiss.Open();

                                if (bool.Parse(extension[2]))
                                {
                                    poRemoval.Parameters.AddWithValue("@po_id", extension[0]);
                                    poRemoval.ExecuteNonQuery();
                                }
                                else
                                {
                                    poStorage.Parameters.AddWithValue("@po_id", extension[0]);
                                    poStorage.Parameters.AddWithValue("@po_sent", DateTime.FromBinary(long.Parse(extension[1])));
                                    poStorage.Parameters.AddWithValue("@po_received", DateTime.Now);
                                    poStorage.Parameters.AddWithValue("@po", largeMessage.DataBuffer);

                                    poStorage.ExecuteNonQuery();
                                }

                                kiss.Close();
                                scope.Complete();
                            }

                if (mode != KissTransactionMode.DTC)
                {
                    msmqTransaction.Commit();
                }
            }
            catch
            {
                if (msmqTransaction != null && mode == KissTransactionMode.MSMQ)
                {
                    msmqTransaction.Abort();
                }

                throw;
            }
            finally
            {
                if (msmqTransaction != null)
                {
                    msmqTransaction.Dispose();
                }
            }
        }
Beispiel #17
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();
                    }
                }
            }
        }
Beispiel #18
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();
                    }
                }
            }
        }
Beispiel #19
0
        private bool WaitForSelfStage(bool wait, DateTime?initialLastUpdate,
                                      out long selfId, out DateTime?selfLastUpdate)
        {
            bool         done;
            SqlParameter sequenceNumber,
                         lastUpdate;
            var dialogLifetime = Kiss.GetTimeout(KissTimeout.KISS_SSSB_STAGELIST);
            var sqltoBundle    = Kiss.GetTimeout(KissTimeout.KISS_SQL_STAGELIST);

            selfId         = ID_NO_ANSWER_FROM_BACKEND;
            selfLastUpdate = null;

            do
            {
                using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                    using (var stageRetrieval =
                               new SqlCommand(PROCEDURE_STAGE_RETRIEVAL, kiss)
                    {
                        CommandTimeout = sqltoBundle, CommandType = CommandType.StoredProcedure
                    })
                    {
                        stageRetrieval.Parameters.AddWithValue("@self", 1);
                        sequenceNumber = stageRetrieval.Parameters.Add("@sequence_number", SqlDbType.BigInt);
                        lastUpdate     = stageRetrieval.Parameters.Add("@last_update", SqlDbType.DateTime);

                        sequenceNumber.Direction = lastUpdate.Direction = ParameterDirection.Output;
                        lastUpdate.IsNullable    = true;

                        kiss.Open();
                        stageRetrieval.ExecuteNonQuery();
                        kiss.Close();

                        selfId         = (long)sequenceNumber.Value;
                        selfLastUpdate = ((SqlDateTime)lastUpdate.SqlValue).IsNull ? null : (DateTime?)lastUpdate.Value;

                        if (wait)
                        {
                            if (initialLastUpdate == null)
                            {
                                done = selfId != ID_NO_ANSWER_FROM_BACKEND;
                            }
                            else
                            {
                                done = selfLastUpdate != initialLastUpdate;
                            }
                        }
                        else
                        {
                            done = selfId != ID_NO_ANSWER_FROM_BACKEND;
                        }
                    }

                if (wait && !done)
                {
                    Thread.Sleep(SLEEP_STAGE_RETRIEVAL);
                }

                dialogLifetime -= SLEEP_STAGE_RETRIEVAL / 1000;
            } while (dialogLifetime >= 0 && wait && !done);

            return(done);
        }
        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 OnProcessMessage(KissTransactionMode mode, MessageQueue queue, Guid conversation)
        {
            string[] extension;
            string   bundleSentChar;
            DateTime bundleSent;
            MessageQueueTransaction msmqTransaction = null;
            var convMessages = LargeMessage.GetMessagesOfConversation(queue, conversation);
            var largeMessage = new LargeMessage(_msmqCapacity, null);
            var dtctoBundle  = TimeSpan.FromSeconds(Kiss.GetTimeout(KissTimeout.BUNDLE_DTC_STORAGE));
            var sqltoBundle  = Kiss.GetTimeout(KissTimeout.BUNDLE_SQL_STORAGE);

            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, dtctoBundle))
                    using (var kiss = new SqlConnection(Kiss.GetConnection(_sql)))
                        using (var bundleStorage =
                                   new SqlCommand(PROCEDURE_BUNDLE_STORAGE, kiss)
                        {
                            CommandTimeout = sqltoBundle,
                            CommandType = CommandType.StoredProcedure
                        })
                        {
                            if (mode == KissTransactionMode.DTC)
                            {
                                largeMessage.Receive(queue, null, convMessages,
                                                     Kiss.GetTimeout(KissTimeout.BUNDLE_RECEIVE_TIMEOUT));
                            }
                            else
                            {
                                using (var suppress = new TransactionScope(TransactionScopeOption.Suppress))
                                {
                                    msmqTransaction = new MessageQueueTransaction();
                                    msmqTransaction.Begin();

                                    largeMessage.Receive(queue, msmqTransaction, convMessages,
                                                         Kiss.GetTimeout(KissTimeout.BUNDLE_RECEIVE_TIMEOUT));

                                    suppress.Complete();
                                }
                            }

                            extension = largeMessage.DecodeExtension();

                            bundleSent     = DateTime.FromBinary(long.Parse(extension[2]));
                            bundleSentChar = bundleSent.ToString(FORMAT_BUNDLE_SENT, DateTimeFormatInfo.InvariantInfo);

                            bundleStorage.Parameters.AddWithValue("@bundle_id", long.Parse(extension[0]));
                            bundleStorage.Parameters.AddWithValue("@client_id", extension[1]);
                            bundleStorage.Parameters.AddWithValue("@bundle_sent", bundleSent);
                            bundleStorage.Parameters.AddWithValue("@bundle_received", DateTime.Now);
                            bundleStorage.Parameters.AddWithValue("@bundle_sent_char", bundleSentChar);
                            bundleStorage.Parameters.AddWithValue("@bundle", largeMessage.DataBuffer);

                            kiss.Open();
                            bundleStorage.ExecuteNonQuery();
                            kiss.Close();

                            scope.Complete();
                        }

                if (mode != KissTransactionMode.DTC)
                {
                    msmqTransaction.Commit();
                }
            }
            catch
            {
                if (msmqTransaction != null && mode == KissTransactionMode.MSMQ)
                {
                    msmqTransaction.Abort();
                }

                throw;
            }
            finally
            {
                if (msmqTransaction != null)
                {
                    msmqTransaction.Dispose();
                }
            }
        }