///|
/// 进程状态
pub(all) enum ProcessStatus {
Created
Running
Suspended
Terminated
} derive(Debug, Eq)
///|
/// 进程动作:描述进程的下一步行为
///
/// 进程行为函数返回 `ProcessAction` 与调度器交互,实现协程式挂起-恢复:
/// - `Done`:进程执行完毕
/// - `Timeout`:延时 `duration` 后执行 `next`,仿真时间推进
/// - `WaitEvent`:等待 `event` 触发后执行 `next`
/// - `Terminate`:立即终止进程
///
/// # Example
/// ```mbt check
/// test {
/// let env = @core.new_env(until=20.0)
/// let log : Array[String] = []
/// ignore(
/// process(env, name="timer", behavior=fn(_) {
/// log.push("start at \{env.now()}")
/// Timeout(duration=5.0, next=fn() {
/// log.push("resume at \{env.now()}")
/// Done
/// })
/// }),
/// )
/// env.run()
/// assert_eq(log[0], "start at 0")
/// assert_eq(log[1], "resume at 5")
/// }
/// ```
pub(all) enum ProcessAction {
Done
Timeout(duration~ : Double, next~ : () -> ProcessAction)
WaitEvent(event~ : @core.Event, next~ : () -> ProcessAction)
Terminate
}
///|
/// 进程行为函数类型
pub type ProcessBehavior = (Process) -> ProcessAction
///|
/// 仿真进程
///
/// 基于指令式协程调度。进程行为函数返回 `ProcessAction` 描述下一步行为,
/// 引擎根据动作调度恢复事件,在事件触发时执行 `next` 续延。
/// 不占用操作系统线程,支持上万并发进程。
pub(all) struct Process {
id : @core.ProcessId
name : String
mut status : ProcessStatus
behavior : ProcessBehavior
}
///|
/// 创建仿真进程并注册到环境
///
/// 进程在 `env.run()` 时按调度顺序执行其 behavior。
/// behavior 返回 `ProcessAction` 描述进程的下一步行为。
pub fn process(
env : @core.SimulationEnv,
name? : String = "",
behavior~ : ProcessBehavior,
) -> Process {
let id = env._alloc_process_id()
let p : Process = { id, name, status: Created, behavior }
// 在 time=0 调度进程启动
ignore(env.schedule(time=0.0, callback=fn() { p._start(env) }))
p
}
///|
/// 启动进程:执行 behavior 并处理返回的 action
fn Process::_start(self : Process, env : @core.SimulationEnv) -> Unit {
self.status = Running
self._run_action(env, (self.behavior)(self))
}
///|
/// 执行 action:根据动作类型调度恢复或终止
fn Process::_run_action(
self : Process,
env : @core.SimulationEnv,
action : ProcessAction,
) -> Unit {
match action {
Done => self.status = Terminated
Terminate => self.status = Terminated
Timeout(duration~, next~) => {
self.status = Suspended
ignore(
env.schedule(time=env.now() + duration, callback=fn() {
self.status = Running
self._run_action(env, next())
}),
)
}
WaitEvent(event~, next~) => {
self.status = Suspended
event.add_callback(fn() {
self.status = Running
self._run_action(env, next())
})
}
}
}
///|
/// 进程是否存活
pub fn Process::is_alive(self : Process) -> Bool {
!(self.status is Terminated)
}
///|
/// 获取进程 ID
pub fn Process::id(self : Process) -> @core.ProcessId {
self.id
}
///|
/// 获取进程名称
pub fn Process::name(self : Process) -> String {
self.name
}