public bool Equals(KeyValueEntry other) { return(bucketAndKey.Equals(other.bucketAndKey) && Created.Equals(other.Created) && Revision == other.Revision && Delta == other.Delta && Operation.Equals(other.Operation) && DataLength == other.DataLength && Validator.Equal(Value, other.Value)); }
public void PurgeDeletes(KeyValuePurgeOptions options) { long dmThresh = options == null ? KeyValuePurgeOptions.DefaultThresholdMillis : options.DeleteMarkersThresholdMillis; DateTime limit; if (dmThresh < 0) { limit = DateTime.UtcNow.AddMilliseconds(600000); // long enough in the future to clear all } else if (dmThresh == 0) { limit = DateTime.UtcNow.AddMilliseconds(KeyValuePurgeOptions.DefaultThresholdMillis); } else { limit = DateTime.UtcNow.AddMilliseconds(-dmThresh); } IList <string> noKeepList = new List <string>(); IList <string> keepList = new List <string>(); VisitSubject(KeyValueUtil.ToStreamSubject(BucketName), DeliverPolicy.LastPerSubject, true, false, m => { KeyValueEntry kve = new KeyValueEntry(m); if (!kve.Operation.Equals(KeyValueOperation.Put)) { if (kve.Created > limit) // created > limit, so created after { keepList.Add(new BucketAndKey(m).Key); } else { noKeepList.Add(new BucketAndKey(m).Key); } } }); foreach (string key in noKeepList) { jsm.PurgeStream(StreamName, PurgeOptions.WithSubject(RawKeySubject(key))); } foreach (string key in keepList) { PurgeOptions po = PurgeOptions.Builder() .WithSubject(RawKeySubject(key)) .WithKeep(1) .Build(); jsm.PurgeStream(StreamName, po); } }
internal KeyValueEntry _kvGetMessage(string key, ulong revision) { try { KeyValueEntry kve = new KeyValueEntry(jsm.GetMessage(StreamName, revision)); return(key.Equals(kve.Key) ? kve : null); } catch (NATSJetStreamException njse) { if (njse.ApiErrorCode == JetStreamConstants.JsNoMessageFoundErr) { return(null); } throw; } }
public ulong Create(string key, byte[] value) { try { return(Update(key, value, 0)); } catch (NATSJetStreamException e) { if (e.ApiErrorCode == JetStreamConstants.JsWrongLastSequence) { // must check if the last message for this subject is a delete or purge KeyValueEntry kve = _kvGetLastMessage(key); if (kve != null && !kve.Operation.Equals(KeyValueOperation.Put)) { return(Update(key, value, kve.Revision)); } } throw; } }
public KeyValueWatchSubscription(KeyValue kv, string keyPattern, IKeyValueWatcher watcher, params KeyValueWatchOption[] watchOptions) { string subject = kv.RawKeySubject(keyPattern); // figure out the result options bool headersOnly = false; bool includeDeletes = true; DeliverPolicy deliverPolicy = DeliverPolicy.LastPerSubject; foreach (KeyValueWatchOption wo in watchOptions) { switch (wo) { case KeyValueWatchOption.MetaOnly: headersOnly = true; break; case KeyValueWatchOption.IgnoreDelete: includeDeletes = false; break; case KeyValueWatchOption.UpdatesOnly: deliverPolicy = DeliverPolicy.New; break; case KeyValueWatchOption.IncludeHistory: deliverPolicy = DeliverPolicy.All; break; } } if (deliverPolicy == DeliverPolicy.New) { endOfDataSent = new InterlockedBoolean(true); watcher.EndOfData(); } else { KeyValueEntry kveCheckPending = kv._kvGetLastMessage(keyPattern); if (kveCheckPending == null) { endOfDataSent = new InterlockedBoolean(true); watcher.EndOfData(); } else { endOfDataSent = new InterlockedBoolean(false); } } PushSubscribeOptions pso = PushSubscribeOptions.Builder() .WithStream(kv.StreamName) .WithOrdered(true) .WithConfiguration( ConsumerConfiguration.Builder() .WithAckPolicy(AckPolicy.None) .WithDeliverPolicy(deliverPolicy) .WithHeadersOnly(headersOnly) .WithFilterSubject(subject) .Build()) .Build(); EventHandler <MsgHandlerEventArgs> handler = (sender, args) => { KeyValueEntry kve = new KeyValueEntry(args.msg); if (includeDeletes || kve.Operation.Equals(KeyValueOperation.Put)) { watcher.Watch(kve); } if (endOfDataSent.IsFalse() && kve.Delta == 0) { endOfDataSent.Set(true); watcher.EndOfData(); } }; sub = kv.js.PushSubscribeAsync(subject, handler, false, pso); if (endOfDataSent.IsFalse()) { ulong pending = sub.GetConsumerInformation().CalculatedPending; if (pending == 0) { endOfDataSent.Set(true); watcher.EndOfData(); } } }