Skip to content

Commit

Permalink
Dev (#518)
Browse files Browse the repository at this point in the history
  • Loading branch information
joesdu authored Sep 4, 2024
2 parents 772b07a + 9d80e4c commit 7815ac3
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 26 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ EasilyNET Packages
- 对 MongoDB 驱动的一些封装,方便使用以及一些常用的默认配置
- 雪花 ID,一些常用的数据类型,枚举,扩展方法等
- 自动模块化注入服务,新增支持 WPF,WinForm 等项目,需使用 IHost 通用主机模式
- MongoDB 添加 DateOnly 和 TimeOnly 的支持
- MongoDB 添加 DateOnly 和 TimeOnly 的支持, dynamic 类型支持
- MongoDB GridFS 用法的简单支持(常用用法)和使用案例.
- 在 WebAPI 中集成一些常见的过滤器和中间件
- 对 Swagger 文档添加分组,隐藏 API 和添加部分数据类型默认值显示的支持,方便前端工程师查阅
Expand All @@ -54,7 +54,7 @@ EasilyNET Packages
- Some encapsulation of MongoDB driver for easy use and some common default configurations
- Snowflake ID, some common data types, enumerations, extension methods, etc.
- Automatic modular injection services, adding support for WPF, WinForm and other projects, using IHost common host mode
- Added support for DateOnly and TimeOnly in MongoDB
- Added support for DateOnly and TimeOnly in MongoDB, dynamic type support
- Simple support for MongoDB GridFS usage (common usage) and usage examples.
- Integration of some common filters and middleware in WebAPI
- Added support for grouping, hiding APIs, and displaying default values for some data types in Swagger documents, making it easier for front-end engineers to refer to
Expand Down
33 changes: 32 additions & 1 deletion sample/WebApi.Test.Unit/Controllers/MongoLockController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,39 @@ namespace WebApi.Test.Unit.Controllers;
/// MongoDB分布式锁测试
/// </summary>
[Route("api/[controller]/[action]"), ApiController, ApiGroup("MongoLock", "v1", "基于MongoDB实现的分布式锁测试")]
public class MongoLockController(IMongoLockFactory lockFactory) : ControllerBase
public class MongoLockController(IMongoLockFactory lockFactory, DbContext db) : ControllerBase
{
/// <summary>
/// 测试锁
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task BusinessTest()
{
const string lockId = "64d44afda4473b85a177084d"; // 这里使用一个随机的ID作为锁ID,相当于其他锁中的Key.用来区分不同的业务的锁
var mongoLock = lockFactory.GenerateNewLock(ObjectId.Parse(lockId));
var acq = await mongoLock.AcquireAsync(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(0));
try
{
if (acq.Acquired)
{
await db.GetCollection<dynamic>("locks_test").InsertOneAsync(new
{
AcquiredId = acq.AcquireId
});
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
finally
{
await mongoLock.ReleaseAsync(acq);
}
}

/// <summary>
/// AcquireLock
/// </summary>
Expand Down
33 changes: 25 additions & 8 deletions sample/WebApi.Test.Unit/Script.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
import { check } from "k6";
import { check, sleep } from "k6";
import http from "k6/http";

export const options = {
stages: [
{ duration: "30s", target: 20 },
{ duration: "1m30s", target: 10 },
{ duration: "20s", target: 0 },
],
stages: [
{ duration: "60s", target: 100 }, // Ramp-up to 100 users over 30s
{ duration: "60s", target: 200 }, // Ramp-up to 200 users over 1 minute
{ duration: "60s", target: 300 }, // Ramp-up to 300 users over 1 minute
{ duration: "60s", target: 500 }, // Ramp-down to 0 users over 1 minute
],
};

export default function () {
const res = http.post("http://localhost:5046/api/MongoTest/MongoPost");
check(res, { "status was 200": (r) => r.status == 200 });
const url = 'http://localhost:8848/api/MongoLock/BusinessTest';

const payload = JSON.stringify({
email: 'aaa',
password: 'bbb'
});

const params = {
headers: {
'Content-Type': 'application/json',
},
};

const res = http.post(url, params);
check(res, { "status was 200": (r) => r.status == 200 });

// Optional: Add a small sleep to simulate real user behavior
sleep(1);
}
3 changes: 3 additions & 0 deletions sample/WebApi.Test.Unit/ServiceModules/MongoModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,12 @@ public override void ConfigureServices(ConfigureServicesContext context)
// }).Build());
// b.AddSimpleConsole();
//}));
cs.MaxConnecting = int.MaxValue;
cs.MaxConnectionPoolSize = int.MaxValue;
};
});
context.Services.RegisterSerializer(new DateOnlySerializerAsString());
context.Services.RegisterSerializer(new TimeOnlySerializerAsString());
context.Services.RegisterDynamicSerializer();
}
}
14 changes: 13 additions & 1 deletion src/EasilyNET.MongoDistributedLock/Acquire.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ namespace EasilyNET.MongoDistributedLock;
/// <inheritdoc />
internal sealed class Acquire : IAcquire
{
private readonly IDistributedLock? _distributedLock;

/// <summary>
/// 构造函数
/// </summary>
/// <param name="acquireId"></param>
public Acquire(ObjectId acquireId)
/// <param name="distributedLock"></param>
public Acquire(ObjectId acquireId, IDistributedLock distributedLock)
{
Acquired = true;
AcquireId = acquireId;
_distributedLock = distributedLock;
}

/// <summary>
Expand All @@ -29,4 +33,12 @@ public Acquire()

/// <inheritdoc />
public ObjectId AcquireId { get; }

public async ValueTask DisposeAsync()
{
if (Acquired && _distributedLock is not null)
{
await _distributedLock.ReleaseAsync(this);
}
}
}
2 changes: 1 addition & 1 deletion src/EasilyNET.MongoDistributedLock/Attributes/IAcquire.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace EasilyNET.MongoDistributedLock.Attributes;
/// <summary>
/// IAcquire
/// </summary>
public interface IAcquire
public interface IAcquire : IAsyncDisposable
{
/// <summary>
/// true if lock successfully acquired; otherwise, false
Expand Down
4 changes: 2 additions & 2 deletions src/EasilyNET.MongoDistributedLock/DistributedLock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ public async Task<IAcquire> AcquireAsync(TimeSpan lifetime, TimeSpan timeout)
var acquire = await _locks.Find(bf.Eq(c => c.Id, _lockId)).FirstOrDefaultAsync();
if (acquire is not null && await WaitSignalAsync(acquire.AcquireId, timeout) == false)
{
return await TryUpdateAsync(lifetime, acquireId) ? new Acquire(acquireId) : new();
return await TryUpdateAsync(lifetime, acquireId) ? new Acquire(acquireId, this) : new();
}
}
return new Acquire(acquireId);
return new Acquire(acquireId, this);
}

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;

// ReSharper disable UnusedMethodReturnValue.Global
// ReSharper disable MemberCanBePrivate.Global
Expand All @@ -25,16 +26,16 @@ public static IServiceCollection RegisterSerializer<T>(this IServiceCollection s
return services;
}

///// <summary>
///// 注册动态类型(<see langword="dynamic" /> | <see langword="object" /> )序列化支持
///// </summary>
///// <param name="services"></param>
///// <returns></returns>
/// <summary>
/// 注册动态类型 [<see langword="dynamic" /> | <see langword="object" />] 序列化支持
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
//[Obsolete("MongoDB.Drive 2.18之前和2.21之后,又默认支持动态类型的序列化了(2.19-2.20之间的版本,仅允许反序列化被视为安全的类型).暂时标记为过时.以后应该会移除")]
//public static IServiceCollection RegisterDynamicSerializer(this IServiceCollection services)
//{
// var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type) || (type.FullName is not null && type.FullName.StartsWith("<>f__AnonymousType")));
// BsonSerializer.RegisterSerializer(objectSerializer);
// return services;
//}
public static IServiceCollection RegisterDynamicSerializer(this IServiceCollection services)
{
var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type) || (type.FullName is not null && type.FullName.StartsWith("<>f__AnonymousType")));
BsonSerializer.RegisterSerializer(objectSerializer);
return services;
}
}

0 comments on commit 7815ac3

Please sign in to comment.