public override void Dispose() { var patcher = new ScriptedJsonPatcher(database); using (var scope = new ScriptedIndexResultsJsonPatcherScope(database, forEntityNames)) { if (string.IsNullOrEmpty(scriptedIndexResults.DeleteScript) == false) { foreach (var kvp in removed) { foreach (var entry in kvp.Value) { patcher.Apply(scope, entry, new ScriptedPatchRequest { Script = scriptedIndexResults.DeleteScript, Values = { { "key", kvp.Key } } }); if (Log.IsDebugEnabled && patcher.Debug.Count > 0) { Log.Debug("Debug output for doc: {0} for index {1} (delete):\r\n.{2}", kvp.Key, scriptedIndexResults.Id, string.Join("\r\n", patcher.Debug)); patcher.Debug.Clear(); } } } } if (string.IsNullOrEmpty(scriptedIndexResults.IndexScript) == false) { foreach (var kvp in created) { try { foreach (var entry in kvp.Value) { patcher.Apply(scope, entry, new ScriptedPatchRequest { Script = scriptedIndexResults.IndexScript, Values = { { "key", kvp.Key } } }); } } catch (Exception e) { Log.Warn("Could not apply index script " + scriptedIndexResults.Id + " to index result with key: " + kvp.Key, e); } finally { if (Log.IsDebugEnabled && patcher.Debug.Count > 0) { Log.Debug("Debug output for doc: {0} for index {1} (index):\r\n.{2}", kvp.Key, scriptedIndexResults.Id, string.Join("\r\n", patcher.Debug)); patcher.Debug.Clear(); } } } } database.TransactionalStorage.Batch(accessor => { foreach (var operation in scope.GetOperations()) { switch (operation.Type) { case ScriptedJsonPatcher.OperationType.Put: database.Documents.Put(operation.Document.Key, operation.Document.Etag, operation.Document.DataAsJson, operation.Document.Metadata, null); break; case ScriptedJsonPatcher.OperationType.Delete: database.Documents.Delete(operation.DocumentKey, null, null); break; default: throw new ArgumentOutOfRangeException("operation.Type"); } } }); } }
public override void Dispose() { bool shouldRetry = false; int retries = 128; Random rand = null; do { using (shouldRetry ? database.TransactionalStorage.DisableBatchNesting() : null) { var patcher = new ScriptedJsonPatcher(database); using (var scope = new ScriptedIndexResultsJsonPatcherScope(database, forEntityNames)) { if (string.IsNullOrEmpty(scriptedIndexResults.DeleteScript) == false) { foreach (var kvp in removed) { foreach (var entry in kvp.Value) { patcher.Apply(scope, entry, new ScriptedPatchRequest { Script = scriptedIndexResults.DeleteScript, Values = { { "key", kvp.Key } } }); if (Log.IsDebugEnabled && patcher.Debug.Count > 0) { Log.Debug("Debug output for doc: {0} for index {1} (delete):\r\n.{2}", kvp.Key, scriptedIndexResults.Id, string.Join("\r\n", patcher.Debug)); patcher.Debug.Clear(); } } } } if (string.IsNullOrEmpty(scriptedIndexResults.IndexScript) == false) { foreach (var kvp in created) { try { foreach (var entry in kvp.Value) { patcher.Apply(scope, entry, new ScriptedPatchRequest { Script = scriptedIndexResults.IndexScript, Values = { { "key", kvp.Key } } }); } } catch (Exception e) { Log.Warn("Could not apply index script " + scriptedIndexResults.Id + " to index result with key: " + kvp.Key, e); } finally { if (Log.IsDebugEnabled && patcher.Debug.Count > 0) { Log.Debug("Debug output for doc: {0} for index {1} (index):\r\n.{2}", kvp.Key, scriptedIndexResults.Id, string.Join("\r\n", patcher.Debug)); patcher.Debug.Clear(); } } } } try { database.TransactionalStorage.Batch(accessor => { foreach (var operation in scope.GetOperations()) { switch (operation.Type) { case ScriptedJsonPatcher.OperationType.Put: database.Documents.Put(operation.Document.Key, operation.Document.Etag, operation.Document.DataAsJson, operation.Document.Metadata, null); break; case ScriptedJsonPatcher.OperationType.Delete: database.Documents.Delete(operation.DocumentKey, null, null); break; default: throw new ArgumentOutOfRangeException("operation.Type: " + operation.Type); } } }); shouldRetry = false; } catch (ConcurrencyException) { if (scriptedIndexResults.RetryOnConcurrencyExceptions && retries-- > 0) { shouldRetry = true; if (rand == null) rand = new Random(); Thread.Sleep(rand.Next(5, Math.Max(retries * 2, 10))); continue; } throw; } } } } while (shouldRetry); }
public override void Dispose() { bool shouldRetry = false; int retries = 128; Random rand = null; do { using (shouldRetry ? database.TransactionalStorage.DisableBatchNesting() : null) { var patcher = new ScriptedJsonPatcher(database); using (var scope = new ScriptedIndexResultsJsonPatcherScope(database, forEntityNames)) { if (string.IsNullOrEmpty(scriptedIndexResults.DeleteScript) == false) { foreach (var kvp in removed) { foreach (var entry in kvp.Value) { try { patcher.Apply(scope, entry, new ScriptedPatchRequest { Script = scriptedIndexResults.DeleteScript, Values = { { "key", kvp.Key } } }); } catch (Exception e) { Log.WarnException("Could not apply delete script " + scriptedIndexResults.Id + " to index result with key: " + kvp.Key, e); } finally { if (Log.IsDebugEnabled && patcher.Debug.Count > 0) { Log.Debug("Debug output for doc: {0} for index {1} (delete):\r\n.{2}", kvp.Key, scriptedIndexResults.Id, string.Join("\r\n", patcher.Debug)); patcher.Debug.Clear(); } } } } } if (string.IsNullOrEmpty(scriptedIndexResults.IndexScript) == false) { foreach (var kvp in created) { try { foreach (var entry in kvp.Value) { patcher.Apply(scope, entry, new ScriptedPatchRequest { Script = scriptedIndexResults.IndexScript, Values = { { "key", kvp.Key } } }); } } catch (Exception e) { Log.WarnException("Could not apply index script " + scriptedIndexResults.Id + " to index result with key: " + kvp.Key, e); } finally { if (Log.IsDebugEnabled && patcher.Debug.Count > 0) { Log.Debug("Debug output for doc: {0} for index {1} (index):\r\n.{2}", kvp.Key, scriptedIndexResults.Id, string.Join("\r\n", patcher.Debug)); patcher.Debug.Clear(); } } } } try { database.TransactionalStorage.Batch(accessor => { foreach (var operation in scope.GetOperations()) { switch (operation.Type) { case ScriptedJsonPatcher.OperationType.Put: if (Log.IsDebugEnabled) { Log.Debug("Perform PUT on {0} for scripted index results {1}", operation.Document.Key, scriptedIndexResults.Id); } database.Documents.Put(operation.Document.Key, operation.Document.Etag, operation.Document.DataAsJson, operation.Document.Metadata, null); break; case ScriptedJsonPatcher.OperationType.Delete: if (Log.IsDebugEnabled) { Log.Debug("Perform DELETE on {0} for scripted index results {1}", operation.DocumentKey, scriptedIndexResults.Id); } database.Documents.Delete(operation.DocumentKey, null, null); break; default: throw new ArgumentOutOfRangeException("operation.Type: " + operation.Type); } } }); shouldRetry = false; } catch (ConcurrencyException ex) { if (scriptedIndexResults.RetryOnConcurrencyExceptions && retries-- > 0) { shouldRetry = true; if (rand == null) { rand = new Random(); } if (Log.IsDebugEnabled) { Log.DebugException(string.Format("Applying PUT/DELETE for scripted index results {0} failed with concurrency exception. Retrying", scriptedIndexResults.Id), ex); } Thread.Sleep(rand.Next(5, Math.Max(retries * 2, 10))); continue; } if (Log.IsDebugEnabled) { Log.DebugException(string.Format("Applying PUT/DELETE for scripted index results {0} failed with concurrency exception {1} times.", scriptedIndexResults.Id, 128 - retries + 1), ex); } throw; } } } } while (shouldRetry); }