mormot.rest.core--TRestRunThreads

海利鸟發表於2024-07-12

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;