Browse Source

添加 UnparallelAttribute 特性,使用路由时,可阻止并行。

master
Elivo 1 month ago
parent
commit
2be2c663e8
  1. 16
      Apewer/UnparallelAttribute.cs
  2. 14
      Apewer/Web/ApiAction.cs
  3. 9
      Apewer/Web/ApiProcessor.cs
  4. 8
      Apewer/Web/ApiUtility.cs

16
Apewer/UnparallelAttribute.cs

@ -0,0 +1,16 @@
using System;
namespace Apewer
{
/// <summary>表示方法不可并行。</summary>
[AttributeUsage(AttributeTargets.Method)]
public sealed class UnparallelAttribute : Attribute
{
/// <summary></summary>
public static implicit operator bool(UnparallelAttribute unparallel) => unparallel != null;
}
}

14
Apewer/Web/ApiAction.cs

@ -2,7 +2,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Text;
namespace Apewer.Web namespace Apewer.Web
{ {
@ -19,6 +18,7 @@ namespace Apewer.Web
string _path = null; string _path = null;
HttpMethod[] _methods = null; HttpMethod[] _methods = null;
ApiParameter[] _parameters = null; ApiParameter[] _parameters = null;
UnparallelAttribute _unparallel = null;
#endregion #endregion
@ -55,6 +55,9 @@ namespace Apewer.Web
} }
} }
/// <summary>不可并行。</summary>
public UnparallelAttribute Unparallel { get => _unparallel; }
/// <summary>生成 JSON 实例。</summary> /// <summary>生成 JSON 实例。</summary>
public Json ToJson() => ToJson(null); public Json ToJson() => ToJson(null);
@ -109,9 +112,10 @@ namespace Apewer.Web
/// <param name="path">URL 路径。</param> /// <param name="path">URL 路径。</param>
/// <param name="methods">HTTP 方法。</param> /// <param name="methods">HTTP 方法。</param>
/// <param name="parameters">参数。</param> /// <param name="parameters">参数。</param>
/// <param name="unparallel">不可并行。</param>
/// <exception cref="ArgumentNullException" /> /// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" /> /// <exception cref="ArgumentException" />
ApiAction(Type type, MethodInfo method, string path, HttpMethod[] methods, ApiParameter[] parameters)
ApiAction(Type type, MethodInfo method, string path, HttpMethod[] methods, ApiParameter[] parameters, UnparallelAttribute unparallel)
{ {
if (type == null) throw new ArgumentNullException(nameof(type)); if (type == null) throw new ArgumentNullException(nameof(type));
if (method == null) throw new ArgumentNullException(nameof(method)); if (method == null) throw new ArgumentNullException(nameof(method));
@ -128,6 +132,7 @@ namespace Apewer.Web
_path = path; _path = path;
_methods = methods; _methods = methods;
_parameters = parameters; _parameters = parameters;
_unparallel = unparallel;
} }
/// <summary>解析控制器类型,获取 API 活动。</summary> /// <summary>解析控制器类型,获取 API 活动。</summary>
@ -213,7 +218,10 @@ namespace Apewer.Web
parameters.Add(parameter); parameters.Add(parameter);
} }
var action = new ApiAction(type, method, path, httpMethods.ToArray(), parameters.ToArray());
// 不可并行
var unparallel = RuntimeUtility.GetAttribute<UnparallelAttribute>(method);
var action = new ApiAction(type, method, path, httpMethods.ToArray(), parameters.ToArray(), unparallel);
actions.Add(action); actions.Add(action);
} }

9
Apewer/Web/ApiProcessor.cs

@ -452,10 +452,7 @@ namespace Apewer.Web
if (initializer != null) if (initializer != null)
{ {
var @continue = true; var @continue = true;
UnparallelLocker.InLock(GetUnparallelKey(controller.GetType()), () =>
{
@continue = initializer.Invoke(controller); @continue = initializer.Invoke(controller);
});
if (!@continue) return; if (!@continue) return;
} }
@ -466,22 +463,16 @@ namespace Apewer.Web
{ {
// 调用 API,获取返回值。 // 调用 API,获取返回值。
_context.Controller = controller; _context.Controller = controller;
UnparallelLocker.InLock(GetUnparallelKey(function.Method), () =>
{
Invoke(_context, function.Method, function.Parameters); Invoke(_context, function.Method, function.Parameters);
});
} }
else else
{ {
// 未匹配到 Function,尝试 Default。 // 未匹配到 Function,尝试 Default。
var @default = ApiUtility.GetDefault(controller); var @default = ApiUtility.GetDefault(controller);
if (@default != null) if (@default != null)
{
UnparallelLocker.InLock(GetUnparallelKey(controller.GetType()), () =>
{ {
@default.Invoke(controller); @default.Invoke(controller);
return; return;
});
} }
// 没有执行任何 Function,尝试枚举。 // 没有执行任何 Function,尝试枚举。

8
Apewer/Web/ApiUtility.cs

@ -736,6 +736,14 @@ namespace Apewer.Web
{ {
try try
{ {
if (exception is IApiException apiException)
{
if (!string.IsNullOrEmpty(apiException.Status))
{
response.Status = apiException.Status.ToLower();
}
}
if (setData) if (setData)
{ {
var json = ToJson(exception); var json = ToJson(exception);

Loading…
Cancel
Save