gpt4 book ai didi

c# - Redis BookSleeve 套接字耗尽

转载 作者:可可西里 更新时间:2023-11-01 11:22:13 26 4
gpt4 key购买 nike

当我使用 BookSleeve 连接到我的 Redis 服务器并从中添加/获取条目时,我收到了一个 SocketException。具体的异常(exception)是:通常只允许每个套接字地址(协议(protocol)/网络地址/端口)的一种用法。

堆栈跟踪指向:BookSleeve.RedisConnectionBase.Wait(Task task) in d:\Dev\BookSleeve\BookSleeve\RedisConnectionBase.cs:2050

我的问题是我是否在我的代码中做错了(很可能)没有正确关闭连接或类似性质的东西?在大约 60 秒内执行大约 16000 次左右的操作后,往往会抛出异常。这似乎不是过多的操作,对吧?

相关代码如下,我很乐意提供任何其他信息。

public Cache.CacheEntry Get(string key, bool updateAccessed)
{
var cacheKey = GetCacheableKey(key);

using (var conn = GetUnsecuredConnection())
{
var entry = conn.Get<Cache.CacheEntry>(cacheKey);
return entry;
}
}

public override void Add(string key, Cache.CacheEntry entry)
{
var cacheKey = GetCacheableKey(key);

using (var conn = GetUnsecuredConnection())
{
using (var trans = conn.CreateTransaction())
{
trans.Set(cacheKey, entry);
trans.Strings.Increment(DbNum, CacheEntryCountKey);
trans.Strings.Increment(DbNum, CacheSizeKey, entry.DataLength);
trans.Sets.Add(DbNum, CacheKeysKey, cacheKey);
trans.Execute();
}
}
}

检索连接(这主要是从 BookSleeve 单元测试中复制的:

protected RedisConnection GetUnsecuredConnection(bool open = true, bool allowAdmin = false, bool waitForOpen = false)
{
var host = ConfigurationManager.AppSettings["Redis.BookSleeve.Host"];
var unsecuredPort = int.Parse(ConfigurationManager.AppSettings["Redis.BookSleeve.UnsecuredPort"]); //TODO: get this setting in a safer manner

var conn = new RedisConnection(host, unsecuredPort, syncTimeout: 5000, ioTimeout: 5000, allowAdmin: allowAdmin);
conn.Error += (s, args) => Log.Error(args.Exception.Message + args.Cause, args.Exception, typeof(RedisProviderBookSleeve));
if (open)
{
var openAsync = conn.Open();
if (waitForOpen) conn.Wait(openAsync);
}
return conn;
}

RedisConnection 对象的通用扩展方法:

public static T Get<T>(this RedisConnection conn, string key, int dbNum = 0)
{
if (typeof (T) == typeof (byte[]))
{
var task = conn.Strings.Get(dbNum, key);
var result = conn.Wait(task);
return (T) (object) result;
}
else
{
var task = conn.Strings.GetString(dbNum, key);
var result = conn.Wait(task);
if (result == null || typeof(T) == typeof(string))
return (T)(object)result;

return JsonSerializer.DeserializeFromString<T>(result);
}
}


public static void Set<T>(this RedisConnection conn, string key, T value, int dbNum = 0)
{
if (typeof (T) == typeof (byte[]))
{
conn.Strings.Set(dbNum, key, value as byte[]);
return;
}

var serializedValue = JsonSerializer.SerializeToString(value);
conn.Strings.Set(dbNum, key, serializedValue);
}

最佳答案

Marc 对这个问题的评论让我重新考虑我是如何利用连接的。我遇到了另一个问题的答案:

Maintaining an open Redis connection using BookSleeve

我最终使用了上述链接答案中的代码,删除了我发布的“GetUnsecuredConnection”方法,现在只需在构建/执行 Redis 操作之前检索打开的连接。

不再有 SocketException,一切似乎都按预期运行。感谢马克的提示!感谢@ofer-zelig 提供的连接代码。

public Cache.CacheEntry Get(string key, bool updateAccessed)
{
var cacheKey = GetCacheableKey(key);

var conn = RedisConnectionGateway.Current.GetConnection();

var entry = conn.Get<Cache.CacheEntry>(cacheKey);
return entry;
}

public override void Add(string key, Cache.CacheEntry entry)
{
var cacheKey = GetCacheableKey(key);

var conn = RedisConnectionGateway.Current.GetConnection();

using (var trans = conn.CreateTransaction())
{
trans.Set(cacheKey, entry);
trans.Strings.Increment(DbNum, CacheEntryCountKey);
trans.Strings.Increment(DbNum, CacheSizeKey, entry.DataLength);
trans.Sets.Add(DbNum, CacheKeysKey, cacheKey);
trans.Execute();
}
}

关于c# - Redis BookSleeve 套接字耗尽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20861281/

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