创建索引时 RavenDB 上的任务取消异常

Task Canceled exception on RavenDB when creating indexes

我在尝试在 RavenDB 3.5 上创建索引时遇到问题

当创建超过 3 个索引时,应用程序就会死掉,得到

Unable to connect to the remote server Status Code: ConnectFailure

索引创建代码非常简单:

    private static void CreateIndexes(IDocumentStore documentStore)
    {
        new PurchaseOrder_QueryByExternalReference().Execute(documentStore);
        new SupplierDocument_QueryBySupplierName().Execute(documentStore);
        new ProductDocument_QueryByProductIdAndName().Execute(documentStore);
        new PurchaseOrderLine_QueryableIndex().Execute(documentStore);
        new PurchaseOrderLine_ForPurchaseOrderIndex().Execute(documentStore);
    }

但如果

IndexCreation.CreateIndexes(typeof(MyIndexClass).Assembly, store);

方法被调用。列表中任何顺序的任何 3 个索引都会发生这种情况。

完整的堆栈跟踪是这样的:

exception {"A task was canceled."} Data: {System.Collections.ListDictionaryInternal} Etag: null HResult: -2146233088 HelpLink: null InnerException: null Message: "A task was canceled." Response: {StatusCode: 503, ReasonPhrase: 'Service Unavailable', Version: 1.1, Content: , Headers: { }} ResponseString: "Unable to connect to the remote server Status Code: ConnectFailure" Source: "Raven.Client.Lightweight" StackTrace: " at Raven.Client.Connection.Implementation.HttpJsonRequest.<>c__DisplayClass36_0.<b__0>d.MoveNext() in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Connection\Implementation\HttpJsonRequest.cs:line 258 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Raven.Client.Connection.Implementation.HttpJsonRequest.d__381.MoveNext() in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Connection\Implementation\HttpJsonRequest.cs:line 312 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Raven.Client.Connection.Implementation.HttpJsonRequest.<ReadResponseJsonAsync>d__35.MoveNext() in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Connection\Implementation\HttpJsonRequest.cs:line 221 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Raven.Client.Connection.Async.AsyncServerClient.<>c__DisplayClass69_0.<<GetIndexAsync>b__0>d.MoveNext() in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Connection\Async\AsyncServerClient.cs:line 726 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Raven.Client.Connection.ReplicationInformerBase1.d__341.MoveNext() in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Connection\ReplicationInformerBase.cs:line 417 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task) at Raven.Client.Connection.ReplicationInformerBase1.d__331.MoveNext() in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Connection\ReplicationInformerBase.cs:line 316 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Raven.Client.Connection.Async.AsyncServerClient.<ExecuteWithReplication>d__1641.MoveNext() in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Connection\Async\AsyncServerClient.cs:line 0 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Raven.Abstractions.Util.AsyncHelpers.<>c__DisplayClass1_11.<<RunSync>b__0>d.MoveNext() in C:\Builds\RavenDB-Stable-3.5\Raven.Abstractions\Util\AsyncHelpers.cs:line 75 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Raven.Abstractions.Util.AsyncHelpers.RunSync[T](Func1 task) in C:\Builds\RavenDB-Stable-3.5\Raven.Abstractions\Util\AsyncHelpers.cs:line 89 at Raven.Client.Connection.ServerClient.GetIndex(String name) in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Connection\ServerClient.cs:line 222\ at Raven.Client.Indexes.AbstractIndexCreationTask.Execute(IDatabaseCommands databaseCommands, DocumentConvention documentConvention) in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Indexes\AbstractIndexCreationTask.cs:line 304 at Raven.Client.DocumentStoreBase.ExecuteIndex(AbstractIndexCreationTask indexCreationTask) in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\DocumentStoreBase.cs:line 102 at Raven.Client.Indexes.AbstractIndexCreationTask.Execute(IDocumentStore store) in C:\Builds\RavenDB-Stable-3.5\Raven.Client.Lightweight\Indexes\AbstractIndexCreationTask.cs:line 221 at Persistence.Database.Adapter.RavenDb.RavenDbDocumentStoreFactory.CreateIndexes(IDocumentStore documentStore) in \my\route\Persistence.Database.Adapter\RavenDb\RavenDbDocumentStoreFactory.cs:line 50 at Persistence.Database.Adapter.RavenDb.RavenDbDocumentStoreFactory.ConfigureDocumentStore(IDocumentStore documentStore) in \my\route\Persistence.Database.Adapter\RavenDb\RavenDbDocumentStoreFactory.cs:line 38 at Persistence.Database.Adapter.RavenDb.RavenDbDocumentStoreFactory.Create(String ravenDbLocation, String ravenDbDatabase) in \my\route\Persistence.Database.Adapter\RavenDb\RavenDbDocumentStoreFactory.cs:line 22 at Persistence.Database.Adapter.PersistenceAdapter.<.ctor>b__8_0() in \my\route\Persistence.Database.Adapter\PersistenceAdapter.cs:line 53 at Persistence.Database.Adapter.PersistenceAdapter.RegisterRavenDbUtilities() in \my\route\Persistence.Database.Adapter\PersistenceAdapter.cs:line 175 at Persistence.Database.Adapter.PersistenceAdapter.RegisterRavenLogic() in \my\route\Persistence.Database.Adapter\PersistenceAdapter.cs:line 86 at Persistence.Database.Adapter.PersistenceAdapter.Initialize() in \my\route\Persistence.Database.Adapter\PersistenceAdapter.cs:line 74 at My-Program.ConfigurePersistentAdapter(Settings settings) in \my\route\MessageQueueListener\MessageQueueListenerService.cs:line 153 at My-Program.AddBootstrapperExtension() in \my\route\net-stock-purchasing-service.MessageQueueListener\MessageQueueListenerService.cs:line 118 at My-Program.Startup() in \my\route\net-stock-purchasing-service.MessageQueueListener\MessageQueueListenerService.cs:line 78" StatusCode: ServiceUnavailable TargetSite: {Void MoveNext()}

这解决了我的问题:

var indexes = IndexCreation.CreateIndexesToAdd(new List<AbstractIndexCreationTask> {...}, store.Conventions);

var alreadyExisting = store.DatabaseCommands.GetIndexes(0, 128)
            .ToDictionary(i => i.Name);

foreach (var index in indexes.Where(i => !alreadyExisting.ContainsKey(i.Name)))
    store.DatabaseCommands.PutIndex(index.Name, index.Definition);

store.DatabaseCommands.PutIndexes(indexes);

在我的例子中,结果证明是由于 ravendb 客户端库和安装的服务器不匹配。我的应用程序是 运行 最新版本的 RavenDB 客户端,服务器使用的是版本 3.0

RavenDB 3.5 发布时,客户端包中出现问题。

如果您 运行 RavenDB.Client 从 3.0.30000 到 3.0.30179,那么它应该可以工作。

如果你是运行更高的版本,那么你会遇到(在某些情况下)这个异常。要解决这个问题,您可以使用 alternate APIstore.DatabaseCommands.PutIndexes.

var indexes = new List<AbstractIndexCreationTask>();
indexes.Add(new MyIndex1());
indexes.Add(new MyIndex2());
indexes.Add(new MyIndex....());

var transfos = new List<AbstractTransformerCreationTask>();
transfos.Add(new MyTransformer1());
transfos.Add(new MyTransformer2());
transfos.Add(new MyTransformer...());

// put indexes in 1 command
var indexesToPut = IndexCreation.CreateIndexesToAdd(indexes, documentStore.Conventions);
documentStore.DatabaseCommands.PutIndexes(indexesToPut);

// don't forget transformers
foreach (var item in transfos)
{
    item.Execute(Store);
}

这应该可以解决您的问题。

我在升级客户端包后遇到了这个问题。请注意,异常仅发生在控制台应用程序中,而不是我的 Web 应用程序中。