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); }
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); } }
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); }
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); }