internal PublishAck publish(string subject, byte[] data, EventHandler <StanAckHandlerArgs> handler)
        {
            string localAckSubject = null;
            long   localAckTimeout = 0;

            string subj      = this.pubPrefix + "." + subject;
            string guidValue = newGUID();

            byte[] b = ProtocolSerializer.createPubMsg(clientID, guidValue, subject, data);

            PublishAck a = new PublishAck(this, guidValue, handler, opts.PubAckWait);

            lock (mu)
            {
                if (nc == null)
                {
                    throw new StanConnectionClosedException();
                }

                if (pubAckMap.isAtCapacity())
                {
                    var bd = pubAckMap;

                    Monitor.Exit(mu);
                    // Wait for space outside of the lock so
                    // acks can be removed.
                    bd.waitForSpace();
                    Monitor.Enter(mu);

                    if (nc == null)
                    {
                        throw new StanConnectionClosedException();
                    }
                }

                pubAckMap.Add(guidValue, a);
                localAckSubject = ackSubject;
                localAckTimeout = opts.ackTimeout;
            }

            try
            {
                nc.Publish(subj, localAckSubject, b);
            }
            catch (Exception e)
            {
                removeAck(guidValue);
                throw e;
            }

            return(a);
        }
        internal PublishAck publish(string subject, byte[] data, EventHandler <StanAckHandlerArgs> handler)
        {
            string localAckSubject = null;
            long   localAckTimeout = 0;

            string subj      = this.pubPrefix + "." + subject;
            string guidValue = newGUID();

            byte[]     b = ProtocolSerializer.createPubMsg(clientID, guidValue, subject, data, connID);
            PublishAck a = null;

            lock (mu)
            {
                if (nc == null)
                {
                    throw new StanConnectionClosedException();
                }

                if (nc.IsReconnecting())
                {
                    throw new StanConnectionException("The NATS connection is reconnecting");
                }

                a = new PublishAck(this, guidValue, handler, opts.PubAckWait);
                while (!pubAckMap.TryAdd(guidValue, a))
                {
                    var bd = pubAckMap;

                    Monitor.Exit(mu);
                    // Wait for space outside of the lock so
                    // acks can be removed.
                    bd.waitForSpace();
                    Monitor.Enter(mu);

                    if (nc == null)
                    {
                        throw new StanConnectionClosedException();
                    }
                }

                localAckSubject = ackSubject;
                localAckTimeout = opts.ackTimeout;
            }

            try
            {
                nc.Publish(subj, localAckSubject, b);

                // Flush to reduce latency.
                //
                // TODO:  Add a soft (non-ping) flush to NATS.net
                // for this type of situation.  Only flush in
                // blocking publish calls.
                if (handler == null)
                {
                    nc.Flush();
                }
            }
            catch
            {
                removeAck(guidValue);
                throw;
            }

            return(a);
        }
Beispiel #3
0
        internal PublishAck publish(string subject, byte[] data, EventHandler <StanAckHandlerArgs> handler)
        {
            string localAckSubject = null;

            string subj      = this.pubPrefix + "." + subject;
            string guidValue = newGUID();

            byte[]     b = ProtocolSerializer.createPubMsg(clientID, guidValue, subject, data, connID);
            PublishAck a = null;

            lock (mu)
            {
                if (nc == null || nc.IsClosed())
                {
                    throw new StanConnectionClosedException();
                }

                if (nc.IsReconnecting())
                {
                    throw new StanConnectionException("The NATS connection is reconnecting");
                }

                a = new PublishAck(this, guidValue, handler, opts.PubAckWait);

                int pingInterval = opts.PingInterval;
                while (!pubAckMap.TryAdd(guidValue, a))
                {
                    Monitor.Exit(mu);
                    // Wait for space outside of the lock so
                    // acks can be removed and other executive
                    // functions can continue
                    pubAckMap.TryWaitForSpace(pingInterval);
                    Monitor.Enter(mu);

                    if (nc == null || nc.IsClosed())
                    {
                        throw new StanConnectionClosedException();
                    }

                    if (nc.IsReconnecting())
                    {
                        throw new StanConnectionException("The NATS connection is reconnecting");
                    }
                }

                localAckSubject = ackSubject;
            }

            try
            {
                nc.Publish(subj, localAckSubject, b);

                // Flush to reduce latency.
                if (handler == null)
                {
                    nc.FlushBuffer();
                }
            }
            catch
            {
                removeAck(guidValue);
                throw;
            }

            return(a);
        }