mormot.rest.core--TRestRunThreads

mormot.rest.core--TRestRunThreads

{ ************ TRestRunThreads - REST 实例的多线程处理 }

  /// 访问 TRest 实例的多线程处理
  TRestRunThreads = class(TSynPersistentLock)
  protected
    fOwner: TRest;        // TRest 实例的所有者
    fBackgroundTimer: TRestBackgroundTimer; // 后台定时器
    fShutdown: boolean;   // 标记是否关闭
  public
    /// 初始化线程处理过程
    constructor Create(aOwner: TRest); reintroduce;
    /// 通知不再允许新的注册
    procedure Shutdown;
    /// 结束线程处理过程
    destructor Destroy; override;
  
    /// 允许在后台线程中安全地执行一个处理方法
    // - 返回一个 TSynBackgroundThreadMethod 实例,准备通过其 RunAndWait() 方法执行任何后台任务
    // - 将正确调用 BeginCurrentThread/EndCurrentThread 方法
    // - 你应该提供一些运行时信息来命名线程,以便进行正确的调试
    function NewBackgroundThreadMethod(const Format: RawUtf8;
      const Args: array of const): TSynBackgroundThreadMethod;
  
    /// 允许以给定速度安全地执行一个过程
    // - 返回一个 TSynBackgroundThreadProcess 实例,准备在循环中以 aOnProcessMS 为周期任务执行提供的 aOnProcess 事件
    // - 将正确调用 BeginCurrentThread/EndCurrentThread 方法
    // - 你应该提供一些运行时信息来命名线程,以便进行正确的调试
    function NewBackgroundThreadProcess(
      const aOnProcess: TOnSynBackgroundThreadProcess; aOnProcessMS: cardinal;
      const Format: RawUtf8; const Args: array of const;
      aStats: TSynMonitorClass=nil): TSynBackgroundThreadProcess;
  
    /// 允许在并行中安全地执行一个过程
    // - 返回一个 TSynParallelProcess 实例,准备在给定的 ThreadCount 线程池中并行执行任何任务
    // - 将正确调用 BeginCurrentThread/EndCurrentThread 方法
    // - 你应该提供一些运行时信息来命名线程,以便进行正确的调试
    function NewParallelProcess(ThreadCount: integer; const Format: RawUtf8;
      const Args: array of const): TSynParallelProcess;
  
    /// 在后台线程中定义一个按秒数周期运行的任务
    // - 可用于在此 TRest 实例上以低速(通常为每几分钟)运行后台维护或监控任务
    // - 将为此 TRest 实例实例化并运行一个共享的 TSynBackgroundTimer 实例,因此所有任务将共享同一个线程
    // - 你可以运行 BackgroundTimer.EnQueue 或 ExecuteNow 方法来实现 FIFO 队列,或强制立即执行该过程
    // - 将按预期调用 BeginCurrentThread/EndCurrentThread,例如日志记录
    function TimerEnable(const aOnProcess: TOnSynBackgroundTimerProcess;
      aOnProcessSecs: cardinal): TRestBackgroundTimer;
  
    /// 取消定义一个按秒数周期运行的任务
    // - 应该通过之前对 TimerEnable() 方法的调用进行注册
    // - 如果成功则返回 true,如果提供的任务未注册则返回 false
    function TimerDisable(const aOnProcess: TOnSynBackgroundTimerProcess): boolean;
  
    /// 在后台执行一次任务,但不等待其完成
    function Once(const aOnProcess: TOnSynBackgroundTimerProcess): boolean;
  
    /// 将在后台线程中收集 CPU 和 RAM 信息
    // - 你可以指定更新频率(以秒为单位)
    // - 通过返回的实例访问信息,该实例映射 TSystemUse.Current 类函数
    // - 如果全局 TSystemUse.Current 已被分配,则不执行任何操作
    function SystemUseTrack(periodSec: integer = 10): TSystemUse;
  
    /// 低级访问,可选择初始化关联的定时器
    // - 此函数是线程安全的
    function EnsureBackgroundTimerExists: TRestBackgroundTimer;
  
    /// 你可以在 TThread.Execute 中调用此方法,以确保在处理过程中将考虑该线程
    // - 此方法将重定向 TRestServer.OnBeginCurrentThread
    procedure BeginCurrentThread(Sender: TThread);
  
    /// 你可以在线程即将结束时调用此方法,以确保例如释放关联的外部数据库连接
    // - 此方法将重定向 TRestServer.OnEndCurrentThread
    procedure EndCurrentThread(Sender: TThread);
  
    /// 定义接口方法在后台线程中的异步执行
    // - 此类允许通过一个伪类实现任何接口,该类将所有方法调用重定向到另一个接口的调用,但作为一个 FIFO
    // 在与 TimerEnable/TimerDisable 过程共享的后台线程中
    // - 它是解决 SOA 回调中最难实现问题的一种优雅方案,即避免重入时的竞态条件
    // 例如,如果回调从一个线程运行,然后回调代码尝试在初始线程的上下文中执行某些操作(由临界区(互斥锁)保护)
    // - 是 BackgroundTimer.AsyncRedirect() 的包装器
    procedure AsyncRedirect(const aGuid: TGuid;
      const aDestinationInterface: IInvokable; out aCallbackInterface;
      const aOnResult: TOnAsyncRedirectResult = nil); overload;
  
    /// 定义接口方法在后台线程中的异步执行(重载版本)
    // - 允许实现与上一个 AsyncRedirect 类似的功能,但接受一个 TInterfacedObject 而不是 IInvokable
    procedure AsyncRedirect(const aGuid: TGuid;
      const aDestinationInstance: TInterfacedObject; out aCallbackInterface;
      const aOnResult: TOnAsyncRedirectResult = nil); overload;
  
    /// 允许对指定的 RawUtf8 字符串池进行后台垃圾收集
    // - 默认情况下,将每 5 分钟运行 Interning.Clean(2)
    // - 设置 InterningMaxRefCount=0 以禁用 Interning 实例的处理过程
    // - 请注意,InterningMaxRefCount 和 PeriodMinutes 参数(如果不为 0),对于所有 TRawUtf8Interning 实例都是通用的(以最后设置的值为准)
    // - 例如,你可以运行以下命令来清理 TDocVariant 字符串池中的 RawUtf8:
    // ! aRest.Run.AsyncInterning(DocVariantType.InternNames);
    // ! aRest.Run.AsyncInterning(DocVariantType.InternValues);
    procedure AsyncInterning(Interning: TRawUtf8Interning;
      InterningMaxRefCount: integer = 2; PeriodMinutes: integer = 5);
  
    /// 定义接口方法调用在一个或多个实例中的重定向
    // - 此类允许通过一个伪类实现任何接口,该类将所有方法调用重定向到一个或多个其他接口
    // - 返回的 aCallbackInterface 将将其所有方法(由 aGuid 标识)重定向到由 IMultiCallbackRedirect.Redirect 处理的内部列表
    // - 典型用法如下:
    // ! fSharedCallback: IMyService;
    // ! fSharedCallbacks: IMultiCallbackRedirect;
    // ! ...
    // !   if fSharedCallbacks = nil then
    // !   begin
    // !     fSharedCallbacks := aRest.Run.MultiRedirect(IMyService, fSharedCallback);
    // !     aServices.SubscribeForEvents(fSharedCallback);
    // !   end;
    // !   fSharedCallbacks.Redirect(TMyCallback.Create,[]);
    // !   // 现在,每次 fSharedCallback 收到一个事件时,之前通过 Redirect() 注册的所有回调都将收到它
    // ! ...
    // !   fSharedCallbacks := nil; // 将停止重定向
    // !                            // 如果需要,则注销回调
    function MultiRedirect(const aGuid: TGuid; out aCallbackInterface;
      aCallBackUnRegisterNeeded: boolean = true): IMultiCallbackRedirect; overload;
  
    /// 对关联定时器的低级访问
    // - 如果尚未调用 EnsureBackgroundTimerExists,则可能包含 nil
    property BackgroundTimer: TRestBackgroundTimer
      read fBackgroundTimer;
  end;
posted @ 2024-07-12 18:12  海利鸟  阅读(31)  评论(0编辑  收藏  举报