public IObserveOperationResult Observe(string key, ulong cas, PersistTo persistTo, ReplicateTo replicateTo, ObserveKeyState persistedKeyState = ObserveKeyState.FoundPersisted, ObserveKeyState replicatedState = ObserveKeyState.FoundNotPersisted) { var hashedKey = this.KeyTransformer.Transform(key); var vbucket = this.poolInstance.GetVBucket(key); var nodes = this.poolInstance.GetWorkingNodes().ToArray(); var command = this.poolInstance.OperationFactory.Observe(hashedKey, vbucket.Index, cas); var runner = new ObserveHandler(new ObserveSettings { PersistTo = persistTo, ReplicateTo = replicateTo, Key = hashedKey, Cas = cas, Timeout = observeTimeout }); //Master only persistence if (replicateTo == ReplicateTo.Zero && persistTo == PersistTo.One) { return(runner.HandleMasterPersistence(poolInstance, persistedKeyState)); } else if (replicateTo == ReplicateTo.Zero && persistTo == PersistTo.Zero) //used for key exists checks { return(runner.HandleMasterOnlyInCache(poolInstance)); } else { return(runner.HandleMasterPersistenceWithReplication(poolInstance, persistedKeyState, replicatedState)); } }
public async Task <bool> ObserveAsync(string key, ulong cas, bool deletion, ReplicateTo replicateTo, PersistTo persistTo, CancellationTokenSource cts) { var criteria = GetDurabilityCriteria(deletion); var keyMapper = _configInfo.GetKeyMapper(); var vBucket = (IVBucket)keyMapper.MapKey(key); var observeParams = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; observeParams.CheckConfiguredReplicas(); var persisted = await CheckPersistToAsync(observeParams).ContinueOnAnyContext(); var replicated = await CheckReplicasAsync(observeParams).ContinueOnAnyContext(); if (persisted && replicated) { return(true); } return(await ObserveEveryAsync(async p => { Log.Debug("trying again: {0}", key); persisted = await CheckPersistToAsync(observeParams).ContinueOnAnyContext(); replicated = await CheckReplicasAsync(observeParams).ContinueOnAnyContext(); return persisted & replicated; }, observeParams, _interval, cts.Token)); }
public GenericError(String comolUniqueID, PersistTo persist) { this.UniqueID = Guid.NewGuid(); this.SentDate = DateTime.Now; this.Day = this.SentDate.Date; this.ComolUniqueID = comolUniqueID; this.Persist = persist; this.Type = ErrorType.GenericError; }
/// <summary> /// Delete a key. /// </summary> /// <param name="key">Key of document to delete</param> /// <param name="persistTo">Durability requirement</param> /// <returns>Status code of Remove operation</returns> public virtual int Delete(string key, PersistTo persistTo = PersistTo.Zero) { var result = _Client.ExecuteRemove(key, persistTo); if (result.Exception != null) { throw result.Exception; } return(result.StatusCode.HasValue ? result.StatusCode.Value : 0); }
public DBerror(String comolUniqueID, PersistTo persist) { this.UniqueID = Guid.NewGuid(); this.SentDate = DateTime.Now; this.Day = this.SentDate.Date; this.SQLparameters = new List <String>(); this.ComolUniqueID = comolUniqueID; this.Persist = persist; this.Type = ErrorType.DBerror; }
/// <summary> /// Gets a list of replica indexes that is the larger of either the <see cref="PersistTo"/> or the <see cref="ReplicateTo"/> value. /// </summary> /// <param name="vBucket">The <see cref="VBucket"/> containing the replica indexes.</param> /// <param name="replicateTo">The <see cref="ReplicateTo"/> value.</param> /// <param name="persistTo">The <see cref="PersistTo"/> value.</param> /// <returns>A list of replica indexes which is the larger of either the <see cref="PersistTo"/> or the <see cref="ReplicateTo"/> value</returns> internal List <int> GetReplicas(IVBucket vBucket, ReplicateTo replicateTo, PersistTo persistTo) { var maxReplicas = (int)replicateTo > (int)persistTo ? (int)replicateTo : (int)persistTo; return(maxReplicas > vBucket.Replicas.Length ? vBucket.Replicas.Where(x => x > -1).ToList() : vBucket.Replicas.Where(x => x > -1).Take(maxReplicas).ToList()); }
/// <summary> /// Update a document. Will fail if key (Id property) doesn't exit. /// </summary> /// <param name="value">New document</param> /// /// <param name="persistTo">Optional durability requirement</param> /// <returns>Status code for Update operation. Successful updates return 0.</returns> public virtual int Update(T value, PersistTo persistTo = PersistTo.Zero) { var result = _Client.ExecuteStore(StoreMode.Replace, value.Id, serializeAndIgnoreId(value), persistTo); if (result.Exception != null) { throw result.Exception; } return(result.StatusCode.Value); }
/// <summary> /// Create a document if key doesn't exist, otherwise update document. /// </summary> /// <param name="value">New document</param> /// <param name="persistTo">Optional durability requirement</param> /// <returns>Status code for Set operation. Successful updates return 0.</returns> public virtual int Save(T value, PersistTo persistTo = PersistTo.Zero) { var key = string.IsNullOrEmpty(value.Id) ? BuildKey(value) : value.Id; var result = _Client.ExecuteStore(StoreMode.Set, key, serializeAndIgnoreId(value), persistTo); if (result.Exception != null) { throw result.Exception; } return(result.StatusCode.Value); }
public FileError(long communityFileID, String message, String comolUniqueID, PersistTo persist) { this.UniqueID = Guid.NewGuid(); this.SentDate = DateTime.Now; this.Day = this.SentDate.Date; this.Message = message; this.ComolUniqueID = comolUniqueID; this.Persist = persist; this.Type = ErrorType.FileError; this.CommunityFileID = communityFileID; this.BaseFileID = Guid.Empty; this.NoticeboardFileID = 0; this.ThesisFileID = 0; }
public Task Remove(string id, TimeSpan?timeout = null, ulong cas = 0, PersistTo persistTo = PersistTo.None, ReplicateTo replicateTo = ReplicateTo.None, DurabilityLevel durabilityLevel = DurabilityLevel.None, CancellationToken token = default(CancellationToken)) { var options = new RemoveOptions { Timeout = timeout, Cas = cas, PersistTo = persistTo, ReplicateTo = replicateTo, DurabilityLevel = durabilityLevel, Token = token }; return(Remove(id, options)); }
public Task <IMutationResult> Insert <T>(string id, T content, TimeSpan?timeout = null, TimeSpan expiration = default(TimeSpan), ulong cas = 0, PersistTo persistTo = PersistTo.None, ReplicateTo replicateTo = ReplicateTo.None, DurabilityLevel durabilityLevel = DurabilityLevel.None, CancellationToken token = default(CancellationToken)) { var options = new InsertOptions { Timeout = timeout, Expiration = expiration, Cas = cas, PersistTo = persistTo, ReplicateTo = replicateTo, DurabilityLevel = durabilityLevel, Token = token }; return(Insert(id, content, options)); }
/// <summary> /// Observes the specified key using the Seqno. /// </summary> /// <param name="key">The key.</param> /// <param name="token">The token.</param> /// <param name="replicateTo">The replicate to.</param> /// <param name="persistTo">The persist to.</param> /// <returns>True if durability constraints were matched.</returns> /// <exception cref="DocumentMutationLostException">Thrown if the observed document was lost during /// a hard failover because the document did not reach the replica in time.</exception> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public bool Observe(MutationToken token, ReplicateTo replicateTo, PersistTo persistTo) { var keyMapper = (VBucketKeyMapper)_configInfo.GetKeyMapper(); var p = new ObserveParams { ReplicateTo = replicateTo, PersistTo = persistTo, Token = token, VBucket = keyMapper[token.VBucketId] }; p.CheckConfiguredReplicas(); var op = new ObserveSeqno(p.Token, _transcoder, _timeout); do { var master = p.VBucket.LocatePrimary(); var result = master.Send(op); var osr = result.Value; p.CheckMutationLost(osr); p.CheckPersisted(osr); if (p.IsDurabilityMet()) { return(true); } if (CheckReplicas(p, op)) { return(true); } //prepare for another attempt op = (ObserveSeqno)op.Clone(); p.Reset(); } while (!op.TimedOut()); return(false); }
public IRemoveOperationResult ExecuteRemove(string key, PersistTo persistTo, ReplicateTo replciateTo) { var removeResult = base.ExecuteRemove(key); if (persistTo == PersistTo.Zero && replciateTo == ReplicateTo.Zero) { return(removeResult); } var observeResult = Observe(key, 0, persistTo, replciateTo, ObserveKeyState.NotFound, ObserveKeyState.LogicallyDeleted); if (observeResult.Success) { observeResult.Combine(removeResult); } else { observeResult.Combine(removeResult); } return(removeResult); }
public TransactionConfig( int maxAttempts, TimeSpan expiration, TimeSpan keyValueTimeout, PersistTo persistTo, ReplicateTo replicateTo, LogLevel logLevel, bool cleanupLostAttempts, bool cleanupClientAttempts, TimeSpan cleanupWindow, TimeSpan cleanupStatsInterval, LogLevel cleanupLogLevel, bool logOnFailure, LogLevel logOnFailureLogLevel, LogLevel cleanupOnFailureLogLevel) { MaxAttempts = maxAttempts; Expiration = expiration; KeyValueTimeout = keyValueTimeout; PersistTo = persistTo; ReplicateTo = replicateTo; LogLevel = logLevel; CleanupLostAttempts = cleanupLostAttempts; CleanupClientAttempts = cleanupClientAttempts; CleanupWindow = cleanupWindow; CleanupStatsInterval = cleanupStatsInterval; CleanupLogLevel = cleanupLogLevel; LogOnFailure = logOnFailure; LogOnFailureLogLevel = logOnFailureLogLevel; CleanupOnFailureLogLevel = cleanupOnFailureLogLevel; }
private IManagerErrors GetManager(PersistTo type, String ComolUniqueID, ErrorType errorType) { IManagerErrors manager = null; switch (type) { case PersistTo.Mail: MailTemplate template = (from t in GetCachedTemplates() where t.Type == errorType select t).FirstOrDefault <MailTemplate>(); ErrorSettings setting = (from s in GetCachedErrorSettings() where s.ComolUniqueID == ComolUniqueID select s).FirstOrDefault <ErrorSettings>(); manager = new ManagerMail(template, setting); break; case PersistTo.File: manager = new ManagerFile(); break; case PersistTo.Database: System.Diagnostics.EventLog.WriteEntry("DEBUG", "PersistTo.Database"); manager = new ManagerDatabase(); break; } return(manager); }
public DecrementOptions Durability(PersistTo persistTo, ReplicateTo replicateTo) { PersistTo = persistTo; ReplicateTo = replicateTo; return(this); }
public MutateInOptions Durability(PersistTo persistTo, ReplicateTo replicateTo) { DurabilityValue = new ValueTuple <PersistTo, ReplicateTo>(persistTo, replicateTo); return(this); }
public static IStoreOperationResult ExecuteStoreJson(this ICouchbaseClient client, StoreMode mode, string key, object value, PersistTo persistTo, ReplicateTo replicateTo = ReplicateTo.Zero) { var json = SerializeObject(value); return(client.ExecuteStore(mode, key, json, persistTo, replicateTo)); }
public IOperationResult <ObserveState> Observe(string key, ulong cas, ReplicateTo replicateTo, PersistTo persistTo) { throw new NotImplementedException(); }
/// <summary> /// Performs an observe event on the durability requirements specified on a key /// </summary> /// <param name="key">The key to observe.</param> /// <param name="cas">The 'Check and Set' value of the key.</param> /// <param name="deletion">True if this is a delete operation.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted to to satisfy the durability constraint.</param> /// <returns></returns> public bool Observe(string key, ulong cas, bool deletion, ReplicateTo replicateTo, PersistTo persistTo) { var criteria = GetDurabilityCriteria(deletion); var keyMapper = _configInfo.GetKeyMapper(); var vBucket = (IVBucket)keyMapper.MapKey(key); var observeParams = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; //Used to terminate the loop at the specific timeout using (var cancellationTokenSource = new CancellationTokenSource(_timeout)) { //perform the observe operation at the set interval and terminate if not successful by the timeout var task = ObserveEvery(p => { //check the master for persistence to disk var master = p.VBucket.LocatePrimary(); var result = master.Send(new Observe(key, vBucket, new AutoByteConverter())); Log.Debug(m => m("Master {0} - {1}", master.EndPoint, result.Value)); var state = result.Value; if (state.KeyState == p.Criteria.PersistState) { Interlocked.Increment(ref p.PersistedToCount); } //Check if durability requirements have been met if (p.IsDurabilityMet()) { return true; } //Key mutation detected so fail if (p.HasMutated(state.Cas)) { return false; } //Run the durability requirement check on each replica var tasks = new List<Task<bool>>(); var replicas = GetReplicas(vBucket, replicateTo, persistTo); replicas.ForEach(x => tasks.Add(CheckReplica(p, x))); //Wait for all tasks to finish Task.WaitAll(tasks.ToArray()); return tasks.All(subtask => subtask.Result); }, observeParams, _interval, cancellationTokenSource.Token); task.Wait(_timeout); return task.Result; } }
public IRemoveOperationResult ExecuteRemove(string key, PersistTo persisTo) { return(ExecuteRemove(key)); }
public IStoreOperationResult ExecuteStore(StoreMode mode, string key, object value, DateTime expiresAt, PersistTo persistTo) { return(ExecuteStoreInternal(mode, key, value, expiresAt)); }
/// <summary> /// Sends an operation to the server while observing it's durability requirements using async/await /// </summary> /// <param name="operation">A binary memcached operation - must be a mutation operation.</param> /// <param name="deletion">True if mutation is a deletion.</param> /// <param name="replicateTo">The durability requirement for replication.</param> /// <param name="persistTo">The durability requirement for persistence.</param> /// <returns> /// The <see cref="Task{IOperationResult}" /> to be awaited on with it's <see cref="Durability" /> status. /// </returns> /// <exception cref="System.NotImplementedException"></exception> public virtual Task <IOperationResult> SendWithDurabilityAsync(IOperation operation, bool deletion, ReplicateTo replicateTo, PersistTo persistTo) { throw new NotImplementedException(); }
/// <summary> /// A durability constraint ensuring that a document has been persisted to the n^th node. /// </summary> /// <param name="persistTo">The <see cref="P:Couchbase.Core.IMutateInBuilder`1.PersistTo" /> value.</param> /// <returns></returns> public IMutateInBuilder <TDocument> WithDurability(PersistTo persistTo) { PersistTo = persistTo; return(this); }
/// <summary> /// Performs an observe event on the durability requirements specified on a key asynchronously /// </summary> /// <param name="key">The key to observe.</param> /// <param name="cas">The 'Check and Set' value of the key.</param> /// <param name="deletion">True if this is a delete operation.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted to to satisfy the durability constraint.</param> /// <returns> A <see cref="Task{bool}"/> representing the aynchronous operation.</returns> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public async Task<bool> ObserveAsync(string key, ulong cas, bool deletion, ReplicateTo replicateTo, PersistTo persistTo) { var criteria = GetDurabilityCriteria(deletion); var keyMapper = _configInfo.GetKeyMapper(); var vBucket = (IVBucket) keyMapper.MapKey(key); var observeParams = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; observeParams.CheckConfiguredReplicas(); var operation = new Observe(key, vBucket, _transcoder, (uint)_timeout); //Used to terminate the loop at the specific timeout using (var cts = new CancellationTokenSource(_timeout)) { //perform the observe operation at the set interval and terminate if not successful by the timeout var task = await ObserveEvery(async p => { //check the master for persistence to disk IServer master; var attempts = 0; while ((master = p.VBucket.LocatePrimary()) == null) { if (attempts++ > 10) { throw new TimeoutException("Could not acquire a server."); } await Task.Delay((int) Math.Pow(2, attempts)); } var result = master.Send(operation); Log.Debug(m => m("Master {0} - {1}", master.EndPoint, result.Value)); var state = result.Value; if (state.KeyState == p.Criteria.PersistState) { Interlocked.Increment(ref p.PersistedToCount); } //Key mutation detected so fail if (p.HasMutated(state.Cas)) { return false; } //Check if durability requirements have been met if (p.IsDurabilityMet()) { return true; } //Run the durability requirement check on each replica var tasks = new List<Task<bool>>(); var replicas = p.GetReplicas(); replicas.ForEach(x => tasks.Add(CheckReplicaAsync(p, operation, x))); //Wait for all tasks to finish await Task.WhenAll(tasks.ToArray()).ContinueOnAnyContext(); var mutated = tasks.All(subtask => subtask.Result); return p.IsDurabilityMet() && !mutated; }, observeParams, operation, _interval, cts.Token).ContinueOnAnyContext(); return task; } }
/// <summary> /// Performs an observe event on the durability requirements specified on a key stored by an delete operation. /// </summary> /// <param name="key">The key to observe.</param> /// <param name="cas">The 'Check and Set' value of the key.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated (deleted) to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted (deleted) to to satisfy the durability constraint.</param> /// <returns>True if the durability constraints have been satisfied.</returns> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public bool ObserveRemove(string key, ulong cas, ReplicateTo replicateTo, PersistTo persistTo) { return Observe(key, cas, true, replicateTo, persistTo); }
/// <summary> /// Performs an observe event on the durability requirements specified on a key stored by an Add operation. /// </summary> /// <param name="key">The key to observe.</param> /// <param name="cas">The 'Check and Set' value of the key.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted to to satisfy the durability constraint.</param> /// <returns>True if the durability constraints have been satisfied.</returns> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public Task<bool> ObserveAddAsync(string key, ulong cas, ReplicateTo replicateTo, PersistTo persistTo) { return ObserveAsync(key, cas, false, replicateTo, persistTo); }
/// <summary> /// Performs an observe event on the durability requirements specified on a key stored by an Add operation. /// </summary> /// <param name="key">The key to observe.</param> /// <param name="cas">The 'Check and Set' value of the key.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted to to satisfy the durability constraint.</param> /// <returns>True if the durability constraints have been satisfied.</returns> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public bool ObserveAdd(string key, ulong cas, ReplicateTo replicateTo, PersistTo persistTo) { return Observe(key, cas, false, replicateTo, persistTo); }
public PrependOptions Durability(PersistTo persistTo, ReplicateTo replicateTo) { PersistTo = persistTo; ReplicateTo = replicateTo; return(this); }
public IStoreOperationResult ExecuteStore(StoreMode mode, string key, object value, PersistTo persistTo, ReplicateTo replicateTo) { return(ExecuteStoreInternal(mode, key, value)); }
/// <summary> /// Sends an operation to the server while observing it's durability requirements using async/await /// </summary> /// <param name="operation">A binary memcached operation - must be a mutation operation.</param> /// <param name="deletion">True if mutation is a deletion.</param> /// <param name="replicateTo">The durability requirement for replication.</param> /// <param name="persistTo">The durability requirement for persistence.</param> /// <returns> /// The <see cref="Task{IOperationResult}" /> to be awaited on with it's <see cref="Durability" /> status. /// </returns> /// <exception cref="System.NotImplementedException"></exception> public virtual Task <IOperationResult> SendWithDurabilityAsync(IOperation operation, bool deletion, ReplicateTo replicateTo, PersistTo persistTo, TaskCompletionSource <IOperationResult> tcs = null, CancellationTokenSource cts = null) { throw new NotImplementedException(); }
public IStoreOperationResult ExecuteStore(StoreMode mode, string key, object value, TimeSpan validFor, PersistTo persistTo) { var expiresAt = this.CurrentDateTime.Add(validFor); return(ExecuteStore(mode, key, value, expiresAt)); }
/// <summary> /// Checks the replicas to see if the key has met the durability constraints defined by the caller. /// </summary> /// <param name="observeParams">The observe parameters.</param> /// <param name="operation">The operation observe operation reference; will be cloned if reused.</param> /// <param name="replicateTo">The replication durability that must be met.</param> /// <param name="persistTo">The persistence durbaility that must be met.</param> /// <returns></returns> bool CheckReplicas(ObserveParams observeParams, Observe operation, ReplicateTo replicateTo, PersistTo persistTo) { //Get the candidate replicas, if none are defined that match the specified durability return false. var replicas = GetReplicas(observeParams.VBucket, replicateTo, persistTo); if (replicas.Count < (int)replicateTo) { return false; } //Check each replica to see if has met the durability constraints specified. A mutation means we failed. var mutated = replicas.All(index => CheckReplica(observeParams, operation, index)); return observeParams.IsDurabilityMet() && !mutated; }
public IObserveOperationResult Observe(string key, ulong cas, PersistTo persistTo, ReplicateTo replicateTo, ObserveKeyState persistedKeyState = ObserveKeyState.FoundPersisted, ObserveKeyState replicatedState = ObserveKeyState.FoundNotPersisted) { throw new NotImplementedException(); }
/// <summary> /// Performs an observe event on the durability requirements specified on a key asynchronously /// </summary> /// <param name="token">The <see cref="MutationToken"/> to compare against.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted to to satisfy the durability constraint.</param> /// <param name="cts"></param> /// <returns> A <see cref="Task{boolean}"/> representing the aynchronous operation.</returns> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public async Task<bool> ObserveAsync(MutationToken token, ReplicateTo replicateTo, PersistTo persistTo, CancellationTokenSource cts) { var keyMapper = (VBucketKeyMapper) _configInfo.GetKeyMapper(); var obParams = new ObserveParams { ReplicateTo = replicateTo, PersistTo = persistTo, Token = token, VBucket = keyMapper[token.VBucketId] }; obParams.CheckConfiguredReplicas(); var persisted = await CheckPersistToAsync(obParams).ContinueOnAnyContext(); var replicated = await CheckReplicasAsync(obParams).ContinueOnAnyContext(); if (persisted && replicated) { Log.DebugFormat("Persisted and replicated on first try: {0}", _key); return true; } return await ObserveEveryAsync(async p => { Log.DebugFormat("trying again: {0}", _key); persisted = await CheckPersistToAsync(obParams).ContinueOnAnyContext(); replicated = await CheckReplicasAsync(obParams).ContinueOnAnyContext(); return persisted & replicated; }, obParams, _interval, cts.Token); }
/// <summary> /// Sends an operation to the server while observing it's durability requirements /// </summary> /// <typeparam name="T">The value for T.</typeparam> /// <param name="operation">A binary memcached operation - must be a mutation operation.</param> /// <param name="deletion">True if mutation is a deletion.</param> /// <param name="replicateTo">The durability requirement for replication.</param> /// <param name="persistTo">The durability requirement for persistence.</param> /// <returns> /// The <see cref="IOperationResult{T}" /> with it's <see cref="Durability" /> status. /// </returns> /// <exception cref="System.NotImplementedException"></exception> public virtual IOperationResult <T> SendWithDurability <T>(IOperation <T> operation, bool deletion, ReplicateTo replicateTo, PersistTo persistTo) { throw new NotImplementedException(); }
public async Task<bool> ObserveAsync(string key, ulong cas, bool deletion, ReplicateTo replicateTo, PersistTo persistTo, CancellationTokenSource cts) { var criteria = GetDurabilityCriteria(deletion); var keyMapper = _configInfo.GetKeyMapper(); var vBucket = (IVBucket)keyMapper.MapKey(key); var observeParams = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; observeParams.CheckConfiguredReplicas(); var persisted = await CheckPersistToAsync(observeParams).ContinueOnAnyContext(); var replicated = await CheckReplicasAsync(observeParams).ContinueOnAnyContext(); if (persisted && replicated) { return true; } return await ObserveEveryAsync(async p => { Log.DebugFormat("trying again: {0}", key); persisted = await CheckPersistToAsync(observeParams).ContinueOnAnyContext(); replicated = await CheckReplicasAsync(observeParams).ContinueOnAnyContext(); return persisted & replicated; }, observeParams, _interval, cts.Token); }
/// <summary> /// Performs an observe event on the durability requirements specified on a key asynchronously /// </summary> /// <param name="token">The <see cref="MutationToken"/> to compare against.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted to to satisfy the durability constraint.</param> /// <returns> A <see cref="Task{bool}"/> representing the aynchronous operation.</returns> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public async Task<bool> ObserveAsync(MutationToken token, ReplicateTo replicateTo, PersistTo persistTo) { var keyMapper = (VBucketKeyMapper)_configInfo.GetKeyMapper(); var obParams = new ObserveParams { ReplicateTo = replicateTo, PersistTo = persistTo, Token = token, VBucket = keyMapper[token.VBucketId] }; obParams.CheckConfiguredReplicas(); var op = new ObserveSeqno(obParams.Token, _transcoder, _timeout); using (var cts = new CancellationTokenSource((int)_timeout)) { //perform the observe operation at the set interval and terminate if not successful by the timeout var task = await ObserveEvery(async p => { IServer master; var attempts = 0; while ((master = p.VBucket.LocatePrimary()) == null) { if (attempts++ > 10) { throw new TimeoutException("Could not acquire a server."); } await Task.Delay((int)Math.Pow(2, attempts)).ContinueOnAnyContext(); } var result = master.Send(op); var osr = result.Value; p.CheckMutationLost(osr); p.CheckPersisted(osr); if (p.IsDurabilityMet()) { return true; } return await CheckReplicasAsync(p, op).ContinueOnAnyContext(); }, obParams, _interval, op, cts.Token).ContinueOnAnyContext(); return task; } }
/// <summary> /// Observes the specified key using the Seqno. /// </summary> /// <param name="key">The key.</param> /// <param name="token">The token.</param> /// <param name="replicateTo">The replicate to.</param> /// <param name="persistTo">The persist to.</param> /// <returns>True if durability constraints were matched.</returns> /// <exception cref="DocumentMutationLostException">Thrown if the observed document was lost during /// a hard failover because the document did not reach the replica in time.</exception> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public bool Observe(MutationToken token, ReplicateTo replicateTo, PersistTo persistTo) { var keyMapper = (VBucketKeyMapper)_configInfo.GetKeyMapper(); var p = new ObserveParams { ReplicateTo = replicateTo, PersistTo = persistTo, Token = token, VBucket = keyMapper[token.VBucketId] }; p.CheckConfiguredReplicas(); var op = new ObserveSeqno(p.Token, _transcoder, _timeout); do { var master = p.VBucket.LocatePrimary(); var result = master.Send(op); var osr = result.Value; p.CheckMutationLost(osr); p.CheckPersisted(osr); if (p.IsDurabilityMet()) { return true; } if (CheckReplicas(p, op)) { return true; } //prepare for another attempt op = (ObserveSeqno)op.Clone(); p.Reset(); } while (!op.TimedOut()); return false; }
/// <summary> /// Performs an observe event on the durability requirements specified on a key. /// </summary> /// <param name="key">The key to observe.</param> /// <param name="cas">The 'Check and Set' value of the key.</param> /// <param name="deletion">True if this is a delete operation.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted to to satisfy the durability constraint.</param> /// <returns>True if the durability constraints have been met.</returns> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public bool Observe(string key, ulong cas, bool deletion, ReplicateTo replicateTo, PersistTo persistTo) { var criteria = GetDurabilityCriteria(deletion); var keyMapper = _configInfo.GetKeyMapper(); var vBucket = (IVBucket)keyMapper.MapKey(key); var p = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; p.CheckConfiguredReplicas(); var operation = new Observe(key, vBucket, _transcoder, (uint)_timeout); do { var master = p.VBucket.LocatePrimary(); var result = master.Send(operation); var state = result.Value; if (state.KeyState == p.Criteria.PersistState) { Interlocked.Increment(ref p.PersistedToCount); } if (!deletion && p.HasMutated(state.Cas)) { return false; } //First check if durability has already been met if (p.IsDurabilityMet()) { return true; } //If not check each replica if (CheckReplicas(p, operation)) { return true; } //prepare for another attempt operation = (Observe)operation.Clone(); p.Reset(); } while (!operation.TimedOut()); return false; }
/// <summary> /// Performs an observe event on the durability requirements specified on a key stored by an Add operation. /// </summary> /// <param name="key">The key to observe.</param> /// <param name="cas">The 'Check and Set' value of the key.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted to to satisfy the durability constraint.</param> /// <returns>True if the durability constraints have been satisfied.</returns> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public Task<bool> ObserveAddAsync(string key, ulong cas, ReplicateTo replicateTo, PersistTo persistTo, CancellationTokenSource cts) { return ObserveAsync(key, cas, false, replicateTo, persistTo, cts); }
/// <summary> /// Sets the <see cref="P:Couchbase.Core.IMutateInBuilder`1.ReplicateTo" /> and <see cref="P:Couchbase.Core.IMutateInBuilder`1.PersistTo" /> values for a document. /// </summary> /// <param name="persistTo">The <see cref="P:Couchbase.Core.IMutateInBuilder`1.PersistTo" /> value.</param> /// <param name="replicateTo">The <see cref="P:Couchbase.Core.IMutateInBuilder`1.ReplicateTo" /> value.</param> /// <returns> /// An <see cref="T:Couchbase.Core.IMutateInBuilder`1" /> reference for chaining operations. /// </returns> public IMutateInBuilder <TDocument> WithDurability(PersistTo persistTo, ReplicateTo replicateTo) { WithDurability(replicateTo); WithDurability(persistTo); return(this); }
/// <summary> /// Gets a list of replica indexes that is the larger of either the <see cref="PersistTo"/> or the <see cref="ReplicateTo"/> value. /// </summary> /// <param name="vBucket">The <see cref="VBucket"/> containing the replica indexes.</param> /// <param name="replicateTo">The <see cref="ReplicateTo"/> value.</param> /// <param name="persistTo">The <see cref="PersistTo"/> value.</param> /// <returns>A list of replica indexes which is the larger of either the <see cref="PersistTo"/> or the <see cref="ReplicateTo"/> value</returns> internal List<int> GetReplicas(IVBucket vBucket, ReplicateTo replicateTo, PersistTo persistTo) { var maxReplicas = (int) replicateTo > (int) persistTo ? (int) replicateTo : (int)persistTo; return maxReplicas > vBucket.Replicas.Length ? vBucket.Replicas.Where(x => x > -1).ToList() : vBucket.Replicas.Where(x => x > -1).Take(maxReplicas).ToList(); }