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;