gpt4 book ai didi

c# - Microsoft.Azure.Cosmos.Table LocationMode.SecondaryOnly RA-GRS 异常 此操作只能针对主存储位置执行

转载 作者:行者123 更新时间:2023-12-03 05:38:53 25 4
gpt4 key购买 nike

在解析使用 SAS token 的连接字符串时,我很难让 Microsoft.Azure.Cosmos.Table 自动初始化 secondaryUri。

因此,我最终在连接字符串中显式指定了 TableSecondaryEndpoint,这可行,但我无法查询辅助端点,因为 SDK 在尝试请求之前就抛出了异常。

在我的测试中,我发现这是 Microsoft.WindowsAzure.Storage.Table 8.7.0(Microsoft.Azure.Cosmos.Table 1.0.6 的基础)中不存在的回归

这一点非常欢迎专家的意见。谢谢。

此处此异常的项目代码(也在下面复制): https://github.com/golfalot/SOshowAzureTableBug

详细说明此处提出的 secondaryUri 初始化问题的附带问题: https://github.com/Azure/azure-cosmos-table-dotnet/issues/36

using System;
using System.Collections.Generic;

using LEGACY_STORAGE = Microsoft.WindowsAzure.Storage;
using LEGACY_RETRY = Microsoft.WindowsAzure.Storage.RetryPolicies;
using LEGACY_TABLE = Microsoft.WindowsAzure.Storage.Table; //8.7.0 because this is the base for 1.0.6

using NEWEST_TABLE = Microsoft.Azure.Cosmos.Table; // version 1.0.6
using Microsoft.Azure.Cosmos.Table; // had to add this to get access CreateCloudTableClient extension method

using System.Diagnostics;

namespace SOshowAzureTableBug
{
class Program
{
// the SAS token is immaterial in reproducing the problem
const string connectionTableSAS = "TableSecondaryEndpoint=http://127.0.0.1:10002/devstoreaccount1-secondary;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;SharedAccessSignature=immaterial";
static void Main(string[] args)
{

/* Legacy Table SDK */
var storageAccountLegacy = LEGACY_STORAGE.CloudStorageAccount.Parse(connectionTableSAS);
var tableClientLegacy = storageAccountLegacy.CreateCloudTableClient();
Debug.Assert(tableClientLegacy.StorageUri.SecondaryUri != null); // demonstrate SecondaryUri initialised

var tableRequestOptionsLegacy = new LEGACY_TABLE.TableRequestOptions () { LocationMode = LEGACY_RETRY.LocationMode.SecondaryOnly };
tableClientLegacy.DefaultRequestOptions = tableRequestOptionsLegacy;

var tableLegacy = tableClientLegacy.GetTableReference("foo"); // don't need table to exist to show the issue
var retrieveOperation = LEGACY_TABLE.TableOperation.Retrieve(string.Empty, string.Empty, new List<string>() { "bar" });

var tableResult = tableLegacy.Execute(retrieveOperation);
Console.WriteLine("Legacy PASS");


/* Newset Table SDK */
var storageAccountNewest = NEWEST_TABLE.CloudStorageAccount.Parse(connectionTableSAS);
var tableClientNewest = storageAccountNewest.CreateCloudTableClient(new TableClientConfiguration());
Debug.Assert(tableClientNewest.StorageUri.SecondaryUri != null); // demonstrate SecondaryUri initialised

var tableRequestOptionsNewest = new NEWEST_TABLE.TableRequestOptions() { LocationMode = NEWEST_TABLE.LocationMode.SecondaryOnly };
tableClientNewest.DefaultRequestOptions = tableRequestOptionsNewest;

var tableNewset = tableClientNewest.GetTableReference("foo"); // don't need table to exist to show the issue
var retrieveOperationNewset = NEWEST_TABLE.TableOperation.Retrieve(string.Empty, string.Empty, new List<string>() { "bar" });

/* throws Microsoft.Azure.Cosmos.Table.StorageException
* Exception thrown while initializing request: This operation can only be executed against the primary storage location
*/
var tableResultNewset = tableNewset.Execute(retrieveOperationNewset);

Console.WriteLine("Press any key to exit");
Console.Read();
}
}
}

最佳答案

我相信您遇到了 SDK 的错误。

当我尝试以下代码时,我收到与您相同的错误:

        var account = CloudStorageAccount.Parse(connectionString);

var requestOptions = new TableRequestOptions()
{
LocationMode = LocationMode.SecondaryOnly
};
var client = account.CreateCloudTableClient();
client.DefaultRequestOptions = requestOptions;
var table = client.GetTableReference("myTable");
var op = TableOperation.Retrieve("", "");
var result1 = table.Execute(op);

我反编译了库代码并找到了罪魁祸首的源代码:

if (commandLocationMode == CommandLocationMode.PrimaryOnly)
{
if (restCMD.LocationMode == LocationMode.SecondaryOnly)
{
throw new InvalidOperationException("This operation can only be executed against the primary storage location.");//This is the error that gets thrown.
}
Logger.LogInformational(executionState.OperationContext, "This operation can only be executed against the primary storage location.", Array.Empty<object>());
executionState.CurrentLocation = StorageLocation.Primary;
restCMD.LocationMode = LocationMode.PrimaryOnly;
}

但是,如果我不在客户端级别设置 DefaultRequestOptions 并在下面的 Execute 方法中指定它,我不会收到错误,但这是因为主要端点被命中而不是辅助端点(我在 Fiddler 中检查过)。

        var account = CloudStorageAccount.Parse(connectionString);

var requestOptions = new TableRequestOptions()
{
LocationMode = LocationMode.SecondaryOnly
};
var client = account.CreateCloudTableClient();
var table = client.GetTableReference("myTable");
var op = TableOperation.Retrieve("", "");
var result1 = table.Execute(op, requestOptions);

解决方法

如果您的目标是从辅助位置查询实体,那么您可以在 CloudTable 上使用 ExecuteQuery 方法,如下所示。这有效(我再次检查了 Fiddler)。

        var account = CloudStorageAccount.Parse(connectionString);

var requestOptions = new TableRequestOptions()
{
LocationMode = LocationMode.SecondaryOnly
};
var client = account.CreateCloudTableClient();
client.DefaultRequestOptions = requestOptions;
var table = client.GetTableReference("myTable");
TableQuery query = new TableQuery();
var result = table.ExecuteQuery(query).ToList();

关于c# - Microsoft.Azure.Cosmos.Table LocationMode.SecondaryOnly RA-GRS 异常 此操作只能针对主存储位置执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60378219/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com