Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Catalog · How the catalog works

Random project

StateMachineDSL

This repository will update the state machine DSL implementation in various languages ​​later.

View on GitHub

Anyone may press Interesting, signed in or not. It helps others find this project.

Member rating

No ratings yet.

Sign in to rate this project.

README

State Machine DSL Version Implementation

1. About

入职之后,一直苦恼公司内部状态机实现,不同模块可能存在不同的状态机实现,每个人的写法均不相同!其中掺杂着大量的switch case选手,真是汗颜!想着在开源社区当中寻求一个合适的状态机引擎实现。在众多状态机引擎实现当中发现@Frank(张建飞)所实现的状态机引擎十分简单高效,更是在大佬的一篇文章实现一个状态机引擎,教你看清DSL的本质的熏陶下步入DSL(Domain Specific Language)世界大门!

本仓库模仿cola-component-statemachine来实现各种语言版本的状态机!

2. Languages

2.1 Delphi

Delphi(Object Pascal)编程语言可能很多人没有听过,一门很古老的语言,个人感觉和C++挺像的,甚至某些方面比C++更加的舒服!因为迫切需要一个该语言版本的,所以优先实现该版本!

Delphi Version: 11.3.

3. Key Points

3.1 状态机是否应该无状态?

在 Colo-StateMachine 中实现的状态机是无状态的,主要是考虑到阿里巴巴的应用场景——互联网服务不仅面临高并发需求,还需要处理复杂的多线程情况。在这种环境下,每当接收到一个新请求时,都需要为其创建一个新的状态机实例。虽然这种做法可以确保状态机的隔离性和独立性,但它也可能导致性能瓶颈,特别是在高并发场景下,频繁的状态机实例化和销毁会占用大量的内存和计算资源,从而影响系统的整体吞吐量和响应时间。

为了优化这一点,可以考虑以下几种策略:

  • 状态池化:使用对象池技术复用状态机实例,而不是每次都创建新的状态机对象。这样可以减少对象创建和销毁的开销,同时提高内存利用率。
  • 无状态状态机的上下文传递:可以通过传递上下文信息(如外部数据和事件)来让一个共享的无状态状态机处理多个并发请求,而不是每次都创建新的状态机实例。每个请求的状态和逻辑由上下文来维持,而不是依赖于状态机内部的状态。
  • 事件驱动架构:采用事件驱动模型,在事件到达时,通过调度器动态分配处理任务,减少状态机的实例化频率。状态的管理和转换可以通过事件队列而不是独立实例来处理,从而分担系统的负载。

这种无状态状态机的设计,可以有效减少并发请求时的资源竞争和上下文切换,同时确保系统具有更高的可扩展性和响应能力。

但是呢?并不是所有的场景都适合无状态状态机,有些场景可能需要保持状态机的状态,比如需要记录状态机的历史状态、回滚状态等。这时候就需要根据具体的业务需求来选择合适的状态机实现方式。

例如本人工作的项目中,可能并不仅仅去进行状态的流转,可能还需要通过判断当前状态机的状态来进行一些特殊的操作,所以在这种情况下,无状态状态机就不太适用了!

有无状态的状态机:

  • 如果系统的负载较轻,并且操作频率较低(比如每次处理一批数据),那么并发性能可能不是主要瓶颈。但是,如果系统需要处理多个设备、多个操作或多个并行任务(比如并发的多个切割任务),那么就需要考虑并发和多线程, 这种情况使用无状态的状态机比较好;
  • 如果有多个线程或设备同时参与处理,那么每个线程或设备的状态应当是隔离的,这样就不需要担心线程安全的问题。在这种情况下,可以使用无状态的状态机模型,因为每个任务独立执行,不会共享状态,避免了对共享资源的争用;
  • 对于复杂的系统和任务,有状态的状态机可能更符合需求,尤其是在任务之间有依赖关系或需要追踪状态变化时。状态机不仅需要控制状态流转,还可能需要根据历史状态进行决策或故障恢复,这时无状态设计可能不再足够满足要求;

[!CAUTION]

注意,Delphi版本目前的实现是无状态的状态机,仿佛和我原来的需求可能背道而驰,之后可能会对其进行修改!这里也是事先没有做好相关的研究,就对着Colo库库一顿模仿!

到后面可能实现的状态机可以通过相关的配置使得其既可以有状态又可以没有状态!这样就可以根据相应的需求构建出相应的状态机!