예제 #1
0
        public Task <string> PublishAsync(string subject, byte[] data)
        {
            PublishAck    a = publish(subject, data, null);
            Task <string> t = new Task <string>(() =>
            {
                a.wait();
                return(a.GUID);
            });

            t.Start();
            return(t);
        }
        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);
        }
예제 #3
0
        private void processAck(object sender, MsgHandlerEventArgs args)
        {
            PubAck pa = new PubAck();

            try
            {
                ProtocolSerializer.unmarshal(args.Message.Data, pa);
            }
            catch (Exception)
            {
                // TODO:  (cls) handle this...
                return;
            }

            PublishAck a = removeAck(pa.Guid);

            if (a != null)
            {
                a.InvokeHandler(pa.Guid, pa.Error);
            }
        }
예제 #4
0
        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);
        }
예제 #5
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);
        }