Git Product home page Git Product logo

lib_fsm's Introduction

Finite State Machine (FSM) library for PostgreSQL (PL/pgSQL)

Features

[x] User-defined state support: let your user specify their own state machine while still ensuring consistency

[x] Multi-tenant: each row/column from your table can reference a state in another state machine

[x] Historical support: successful state changes are recorded

[x] Complete API

[x] Fully tested

[x] Visual graph generation

Convention

A finite state machine has states, events and transitions.

A state machine can go from one state to another state through a transition. State change is triggered with an event.

A transition is a tuple of a start (previous) state, the event that will trigger the transition and a next state.

An abstract state machine describe a state machine, its (abstract) state and (abstract) transition.

A state machine is an instance of an abstract state machine and points to an abstract state, thus an abstract state machine. A consistent naming convention is essential to build a futur-proof project. Use shared SQL convention as well as an SQL linter.

state name
  • must be a verb

  • verb tense must be either at the simple past (+ed) or at present progressive (+ing)

  • lower-case

  • snake_case if multiple words (e.g. locked_out)

Examples: opened, loading, loaded, recorded, closed, locked, dumped, shipped, finished, running, failed, entered, enabled, disabled, approved, published, archived, activated, pending, pending_renewal, expired, ordered, canceled, returned, refunded, checked_out

event name
  • should be a single word (use snake_case otherwise)

  • must be a verb

  • verb tense must be infinitive

  • lower-case

Examples: start, open, close, lock, unlock, load, unload, dump, ship, fail, enter, enable, disable, run, return, order, cancel, refund, confirm

Usage

API

What was tried before current implementation

Why did they do that?

I would not have done this way

Try #1 Listen to every table column changes

A trigger on every tables that listen to the table state column and that have a custom type like lib_fsm.state_machine to know it must be monitored.

  • Cons:

    • Custom types in PostgreSQL requires a C extension

    • C extensions are not supported in PostgreSQL managed environments

Rejected.

Try #2 Composite type

The previous idea but instead of a custom type, we rely on a composite type (last_state, abstract_machine__id).

  • Pros:

    • Easier to maintain

    • Does not need column names convention

  • Cons:

    • No foreign key on abstract_machine__id (ensure referential integrity with a trigger)

    • No foreign key on abstract_machine__id (ensuring referential integrity with a trigger would require a schema introspection to retrieve all columns of type lib_fsm.state_machine.abstract_machine\__id === old.abstract_machine__id)

Rejected.

Try #3 External table to store every states

Externalize each machine current states to an independent table. Each state is linked to a finite state machine (see abstract state machine).

  • Pros:

    • The table schema explicitly states that one of more columns are each linked to their state machine

    • Supports multiple state (e.g. a contract might two columns, a signed_status and a writing_status)

  • Cons:

    • Looking at a table, you don’t know the value of the current state (e.g. a contract status attribute). It requires an extra join.

Visual documentation generator

PGPASSWORD=$USER_PASSWORD psql -qtAX  -U $USER --password -c "select lib_fsm.state_machine_get_mermaid('081d831f-8f88-4650-aebe-4360599d4bdc') as mermaid;"

Next steps

  • ❏ add support for versioning

  • ❏ add support for transition properties

  • ❏ add support for transition triggers: 0-N triggers, what events should automatically trigger the transition

  • ❏ add support for transition conditions: 0-N (cf: ui-predicate), requires implementing lib_rule_engine first

  • ❏ add support for transition pre_conditions: 0-N, these pre-conditions are run before displaying available events from 'from_state' post_actions (0-N, what to do once we switched to to_state) ⇐ WONT_IMPLEMENT

SQL Conventions

lib_fsm's People

Contributors

fgribreau avatar juliendangers avatar netwoci avatar rlebran avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.