SlideShare a Scribd company logo
1 of 90
Download to read offline
A SHORT TALE ABOUT


STATE MACHINE
Once upon a time…
Kelly
final class Payment


{


private bool $pending = false;


}
Th
e end of chapter 1
A few days later
final class Payment


{


private bool $pending = false;


private bool $failed = false;


}
final class Payment


{


private bool $pending = false;


private bool $failed = false;


}
final class Payment


{


public const NEW = 1;


public const PENDING = 2;


public const FAILED = 3;


private int $state = self::NEW;


}
?
State Machine
(Q, Σ, δ, q0, F)


Q = a
fi
nite set of states


Σ = a
fi
nite, nonempty input alphabet


δ = a series of transition functions


q0 = the starting state


F = the set of accepting states
NEW
PENDING
FAILED PAID
Create
Pay
Fail
Let’s do the research!
De
fi
ne possible states and relation between them


Protect business rules


Integrate other services on transitions
What do we expect?
WinzouStateMachine
Callback’s execution in con
fi
g
fi
le


Used heavily in Sylius


Con
fi
gurable arguments of service


Services have to be public in order to integrate them with state machine


Without stable release, yet battle-tested and robust
$config =
[

'graph' => 'payment'
,

'property_path' => 'state'
,

'states' => ['new','pending','failed','paid']
,

'transitions' =>
[

'process' =>
[

'from' => ['new']
,

'to' => 'pending'
,

]
,

'fail' =>
[

'from' => ['pending']
,

'to' => 'failed'
,

]
,

'pay' =>
[

'from' => ['pending']
,

'to' => 'paid'
,

]
,

]
,

];
$config =
[

'graph' => 'payment'
,

'property_path' => 'state'
,

'states' => ['new','pending','failed','paid'],
'transitions' =>
[

'process' =>
[

'from' => ['new']
,

'to' => 'pending'
,

]
,

'fail' =>
[

'from' => ['pending']
,

'to' => 'failed'
,

]
,

'pay' =>
[

'from' => ['pending']
,

'to' => 'paid'
,

]
,

]
,

];
$config =
[

'graph' => 'payment'
,

'property_path' => 'state',
'states' => ['new','pending','failed','paid']
,

'transitions' => [
'process' =>
[

'from' => ['new']
,

'to' => 'pending'
,

]
,

'fail' =>
[

'from' => ['pending']
,

'to' => 'failed'
,

]
,

'pay' =>
[

'from' => ['pending']
,

'to' => 'paid'
,

]
,

]
,

];
$config =
[

'graph' => 'payment'
,

'property_path' => 'state'
,

'states' => ['new','pending','failed','paid'],
'transitions' =>
[

'process' =>
[

'from' => ['new']
,

'to' => 'pending'
,

]
,

'fail' =>
[

'from' => ['pending']
,

'to' => 'failed'
,

]
,

'pay' =>
[

'from' => ['pending']
,

'to' => 'paid'
,

]
,

]
,

];
Symfony Work
fl
ow
Maintained by Symfony


Flex support


Work
fl
ow & state machine support


Execution of external services with events


XML / YAML / PHP support out-of-the-box


Best documentation hands down
$definitionBuilder = new DefinitionBuilder()
;

$definition = $definitionBuilder->addPlaces(['new','pending','failed','paid']
)

->addTransition(new Transition('process', 'new', 'pending')
)

->addTransition(new Transition('fail', [‘pending'], 'failed')
)

->addTransition(new Transition('pay', 'pending', 'paid')
)

->build(
)

;

$singleState = true
;

$property = 'state'
;

$marking = new MethodMarkingStore($singleState, $property)
;

$workflow = new Workflow($definition, $marking, null, 'payment');
$definitionBuilder = new DefinitionBuilder()
;

$definition = $definitionBuilder->addPlaces(['new','pending','failed','paid']
)

->addTransition(new Transition('process', 'new', 'pending')
)

->addTransition(new Transition('fail', ['pending'], 'failed')
)

->addTransition(new Transition('pay', 'pending', 'paid')
)

->build(
)

;

$singleState = true
;

$property = 'state'
;

$marking = new MethodMarkingStore($singleState, $property)
;

$workflow = new Workflow($definition, $marking, null, 'payment');
$definitionBuilder = new DefinitionBuilder()
;

$definition = $definitionBuilder->addPlaces(['new','pending','failed','paid']
)

->addTransition(new Transition('process', 'new', 'pending')
)

->addTransition(new Transition('fail', [‘pending'], 'failed')
)

->addTransition(new Transition('pay', 'pending', 'paid')
)

->build(
)

;

$singleState = true
;

$property = 'state'
;

$marking = new MethodMarkingStore($singleState, $property)
;

$workflow = new Workflow($definition, $marking, null, 'payment');
Finite
Oldest and most popular implementation


(in terms of stars)


Least used implementation


(in terms of daily installs according to packagist)


Extendability with events & callbacks de
fi
nition


Perhaps reached its EOL


(https://github.com/yohang/Finite/issues/161)


It is said to be little bit heavier implementation compared to Winzou
Back to
the
st
ory…
final class Payment


{


public const NEW = 'new';


private string $state = self::NEW;


public function getState(): string


{


return $this->state;


}


public function setState(string $state): void


{


$this->state = $state


}


}
WinzouStateMachine
$payment = new Payment()
;

$stateMachine = new StateMachine($payment, $config)
;

$stateMachine->apply('process')
;

$stateMachine->apply('fail');
Symfony Work
fl
ow
$payment = new Payment()
;

$workflow->apply($payment, 'process')
;

$workflow->apply($payment, 'fail');
Th
e end of chapter 2
New adventur
e
WinzouStateMachine
final class InventoryOperato
r

{

public function __invoke(TransitionEvent $transitionEvent): voi
d

{

$stateMachine = $transitionEvent->getStateMachine()
;

/** @var Payment $payment *
/

$payment = $stateMachine->getObject()
;

// Reduce inventory of bought product
s

}

}
$config =
[

// ..
.

'callbacks' =>
[

'before' =>
[

'reduce_amount' =>
[

'on' => ['pay']
,

'do' => new InventoryOperator()
,

]
,

]
,

]
,

];
final class InventoryOperato
r

{

public function __invoke(TransitionEvent $transitionEvent): voi
d

{

$stateMachine = $transitionEvent->getStateMachine()
;

/** @var Payment $payment *
/

$payment = $stateMachine->getObject()
;

// Reduce inventory of bought product
s

}

}
$config =
[

// ..
.

'callbacks' =>
[

'before' =>
[

'reduce_amount' =>
[

'on' => ['pay']
,

'do' => new InventoryOperator()
,

]
,

]
,

]
,

];
final class InventoryOperato
r

{

public function __invoke(TransitionEvent $transitionEvent): voi
d

{

$stateMachine = $transitionEvent->getStateMachine()
;

/** @var Payment $payment *
/

$payment = $stateMachine->getObject()
;

// Reduce inventory of bought product
s

}

}
$config =
[

// ..
.

'callbacks' => [
'before' => [
'reduce_amount' =>
[

'on' => ['pay']
,

'do' => new InventoryOperator()
,

]
,

]
,

]
,

];
Guard


Before


After
Callbacks types
* Same can be achieved with dispatched events
class StateMachine implements StateMachineInterface


{


public function apply(/** */): void


{


// Guard callback


if (!$this->can($transition)) {


throw new SMException();


}


// Before callback


$this->setState('failed');


// After callback


}


}
final class InventoryOperato
r

{

public function __invoke(TransitionEvent $transitionEvent): voi
d

{

$stateMachine = $transitionEvent->getStateMachine()
;

/** @var Payment $payment *
/

$payment = $stateMachine->getObject()
;

// Reduce inventory of bought product
s

}

}
$config =
[

// ..
.

'callbacks' =>
[

'before' =>
[

'reduce_amount' => [
'on' => ['pay']
,

'do' => new InventoryOperator()
,

]
,

]
,

]
,

];
On -> transition


From -> state


To -> state
Callbacks types
Symfony Work
fl
ow
$dispatcher = new EventDispatcher()
;

$dispatcher->addListener
(

'workflow.payment.enter.paid',
 

new PaymentPaidListener(
)

)
;

$workflow = new Workflow($definition, $marking, $dispatcher, 'payment');
final class PaymentPaidListener


{


public function __invoke(EnterEvent $event): void


{


// Reduce inventory of bought products


}


}
$dispatcher = new EventDispatcher()
;

$dispatcher->addListener
(

'workflow.payment.enter.paid',
 

new PaymentPaidListener(
)

);
$workflow = new Workflow($definition, $marking, $dispatcher, 'payment');
final class PaymentPaidListener


{


public function __invoke(EnterEvent $event): void


{


// Reduce inventory of bought products


}


}
$dispatcher = new EventDispatcher()
;

$dispatcher->addListener(
'workflow.payment.enter.paid',
 

new PaymentPaidListener(
)

)
;

$workflow = new Workflow($definition, $marking, $dispatcher, 'payment');
final class PaymentPaidListener


{


public function __invoke(EnterEvent $event): void


{


// Reduce inventory of bought products


}


}
$dispatcher = new EventDispatcher()
;

$dispatcher->addListener(
'workflow.payment.enter.paid',
new PaymentPaidListener(
)

)
;

$workflow = new Workflow($definition, $marking, $dispatcher, 'payment');
final class PaymentPaidListener


{


public function __invoke(EnterEvent $event): void


{


// Reduce inventory of bought products


}


}
$dispatcher = new EventDispatcher()
;

$dispatcher->addListener(
'workflow.payment.enter.paid',
 

new PaymentPaidListener(
)

)
;

$workflow = new Workflow($definition, $marking, $dispatcher, 'payment');
final class PaymentPaidListener


{


public function __invoke(EnterEvent $event): void


{


// Reduce inventory of bought products


}


}
work
fl
ow.[place type]


work
fl
ow.[work
fl
ow name].[place type]


work
fl
ow.[work
fl
ow name].[place type].[place name]
Actions
leave -> current place


enter -> which place(places) will be visited


entered -> which place(places) were visited
Types for places
work
fl
ow.[transition type]


work
fl
ow.[work
fl
ow name].[transition type]


work
fl
ow.[work
fl
ow name].[transition type].[transition name]
Actions
guard -> possibility to validate transition


transition -> which transition will be executed


completed -> which transition was executed


announce -> which transition are available now
Types for transitions
class Workflow implements WorkflowInterface


{


public function apply(/** */
)

{

$this->leave(/** */)
;

$this->transition(/** */);
$this->enter(/** */)
;

/** Making transition */
$this->markingStore->setMarking($payment, 'failed', $context)
;

$this->entered(/** */)
;

$this->completed(/** */)
;

$this->announce(/** */)
;

}

}
WinzouStateMachine
final class BlockAuthorizer


{


public function __invoke(): bool


{


return false;


}


}
$config =
[

/** ... *
/

'callbacks' =>
[

/** ... *
/

'guard' =>
[

'guard-blocked' =>
[

'to' => ['blocked']
,

'do' => new BlockedAuthorizer()
,

]
,

]
,

]
,

];
Symfony Work
fl
ow
final class BlockedGuardListener


{


public function __invoke(GuardEvent $event): void


{


$event->setBlocked(true);


}


}
$dispatcher->addListener
(

'workflow.payment.guard.block'
,

new BlockedGuardListener(
)

)
;
Th
e end of chapter 3
Summary
De
fi
ne possible states and relation between them


Protect business rules (with guards)


Trigger other services on transitions


Ease to add new possible transitions


Trigger other state changes as a reaction
WinzouStateMachine vs Symfony Work
fl
ow
Why should you care?
Common issues
Business logic wired up in
con
fi
guration
fi
les
Describe problem with state machine


but implement directly in code
Possibility to destroy state of entities


if state machine is omitted
😭
setState(…)
lchrusciel/RawStateMachine
@Sylius
Thank you!
@lukaszchrusciel

More Related Content

What's hot

Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
Bill Chang
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)
Fabien Potencier
 

What's hot (20)

The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Adding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
Introduction to DI(C)
Introduction to DI(C)Introduction to DI(C)
Introduction to DI(C)
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
Frontin like-a-backer
Frontin like-a-backerFrontin like-a-backer
Frontin like-a-backer
 
Injection de dĂŠpendances dans Symfony >= 3.3
Injection de dĂŠpendances dans Symfony >= 3.3Injection de dĂŠpendances dans Symfony >= 3.3
Injection de dĂŠpendances dans Symfony >= 3.3
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Unittests fĂźr Dummies
Unittests fĂźr DummiesUnittests fĂźr Dummies
Unittests fĂźr Dummies
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)
 
Event Sourcing with php
Event Sourcing with phpEvent Sourcing with php
Event Sourcing with php
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
php 2 Function creating, calling, PHP built-in function
php 2 Function creating, calling,PHP built-in functionphp 2 Function creating, calling,PHP built-in function
php 2 Function creating, calling, PHP built-in function
 

Similar to Dutch php a short tale about state machine

Similar to Dutch php a short tale about state machine (20)

A short tale about state machine
A short tale about state machineA short tale about state machine
A short tale about state machine
 
PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2PHPUnit elevato alla Symfony2
PHPUnit elevato alla Symfony2
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
A short tale about state machine
A short tale about state machineA short tale about state machine
A short tale about state machine
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application framework
 
PHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くためにPHPUnit でよりよくテストを書くために
PHPUnit でよりよくテストを書くために
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
Practical approach for testing your software with php unit
Practical approach for testing your software with php unitPractical approach for testing your software with php unit
Practical approach for testing your software with php unit
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
 
Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)
 
How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-london
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
“SOLID principles in PHP – how to apply them in PHP and why should we care“ b...
“SOLID principles in PHP – how to apply them in PHP and why should we care“ b...“SOLID principles in PHP – how to apply them in PHP and why should we care“ b...
“SOLID principles in PHP – how to apply them in PHP and why should we care“ b...
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 

More from Łukasz Chruściel

More from Łukasz Chruściel (17)

Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
ConFoo 2024 - Need for Speed: Removing speed bumps in API Projects
ConFoo 2024  - Need for Speed: Removing speed bumps in API ProjectsConFoo 2024  - Need for Speed: Removing speed bumps in API Projects
ConFoo 2024 - Need for Speed: Removing speed bumps in API Projects
 
ConFoo 2024 - Sylius 2.0, top-notch eCommerce for customizable solution
ConFoo 2024 - Sylius 2.0, top-notch eCommerce for customizable solutionConFoo 2024 - Sylius 2.0, top-notch eCommerce for customizable solution
ConFoo 2024 - Sylius 2.0, top-notch eCommerce for customizable solution
 
SyliusCon - Typical pitfalls of Sylius development.pdf
SyliusCon - Typical pitfalls of Sylius development.pdfSyliusCon - Typical pitfalls of Sylius development.pdf
SyliusCon - Typical pitfalls of Sylius development.pdf
 
Need for Speed: Removing speed bumps in API Projects
Need for Speed: Removing speed bumps in API ProjectsNeed for Speed: Removing speed bumps in API Projects
Need for Speed: Removing speed bumps in API Projects
 
SymfonyLive Online 2023 - Is SOLID dead? .pdf
SymfonyLive Online 2023 - Is SOLID dead? .pdfSymfonyLive Online 2023 - Is SOLID dead? .pdf
SymfonyLive Online 2023 - Is SOLID dead? .pdf
 
Worldwide Software Architecture Summit'23 - BDD and why most of us do it wron...
Worldwide Software Architecture Summit'23 - BDD and why most of us do it wron...Worldwide Software Architecture Summit'23 - BDD and why most of us do it wron...
Worldwide Software Architecture Summit'23 - BDD and why most of us do it wron...
 
4Developers - Rozterki i decyzje.pdf
4Developers - Rozterki i decyzje.pdf4Developers - Rozterki i decyzje.pdf
4Developers - Rozterki i decyzje.pdf
 
4Developers - Sylius CRUD generation revisited.pdf
4Developers - Sylius CRUD generation revisited.pdf4Developers - Sylius CRUD generation revisited.pdf
4Developers - Sylius CRUD generation revisited.pdf
 
BoilingFrogs - Rozterki i decyzje. Czego się nauczyliśmy projektując API Syliusa
BoilingFrogs - Rozterki i decyzje. Czego się nauczyliśmy projektując API SyliusaBoilingFrogs - Rozterki i decyzje. Czego się nauczyliśmy projektując API Syliusa
BoilingFrogs - Rozterki i decyzje. Czego się nauczyliśmy projektując API Syliusa
 
What we've learned designing new Sylius API
What we've learned designing new Sylius APIWhat we've learned designing new Sylius API
What we've learned designing new Sylius API
 
How to optimize background processes.pdf
How to optimize background processes.pdfHow to optimize background processes.pdf
How to optimize background processes.pdf
 
SymfonyCon - Dilemmas and decisions..pdf
SymfonyCon - Dilemmas and decisions..pdfSymfonyCon - Dilemmas and decisions..pdf
SymfonyCon - Dilemmas and decisions..pdf
 
How to optimize background processes - when Sylius meets Blackfire
How to optimize background processes - when Sylius meets BlackfireHow to optimize background processes - when Sylius meets Blackfire
How to optimize background processes - when Sylius meets Blackfire
 
BDD in practice based on an open source project
BDD in practice based on an open source projectBDD in practice based on an open source project
BDD in practice based on an open source project
 
Diversified application testing based on a Sylius project
Diversified application testing based on a Sylius projectDiversified application testing based on a Sylius project
Diversified application testing based on a Sylius project
 
Why do I love and hate php?
Why do I love and hate php?Why do I love and hate php?
Why do I love and hate php?
 

Recently uploaded

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 

Recently uploaded (20)

Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
 

Dutch php a short tale about state machine

  • 1. A SHORT TALE ABOUT STATE MACHINE
  • 2. Once upon a time…
  • 4.
  • 5. final class Payment { private bool $pending = false; }
  • 6.
  • 7. Th e end of chapter 1
  • 8. A few days later
  • 9.
  • 10. final class Payment { private bool $pending = false; private bool $failed = false; }
  • 11.
  • 12. final class Payment { private bool $pending = false; private bool $failed = false; }
  • 13. final class Payment { public const NEW = 1; public const PENDING = 2; public const FAILED = 3; private int $state = self::NEW; } ?
  • 14.
  • 16. (Q, ÎŁ, δ, q0, F) Q = a fi nite set of states Σ = a fi nite, nonempty input alphabet δ = a series of transition functions q0 = the starting state F = the set of accepting states
  • 18. Let’s do the research!
  • 19. De fi ne possible states and relation between them Protect business rules Integrate other services on transitions What do we expect?
  • 21. Callback’s execution in con fi g fi le Used heavily in Sylius Con fi gurable arguments of service Services have to be public in order to integrate them with state machine Without stable release, yet battle-tested and robust
  • 22.
  • 23.
  • 24. $config = [ 'graph' => 'payment' , 'property_path' => 'state' , 'states' => ['new','pending','failed','paid'] , 'transitions' => [ 'process' => [ 'from' => ['new'] , 'to' => 'pending' , ] , 'fail' => [ 'from' => ['pending'] , 'to' => 'failed' , ] , 'pay' => [ 'from' => ['pending'] , 'to' => 'paid' , ] , ] , ];
  • 25. $config = [ 'graph' => 'payment' , 'property_path' => 'state' , 'states' => ['new','pending','failed','paid'], 'transitions' => [ 'process' => [ 'from' => ['new'] , 'to' => 'pending' , ] , 'fail' => [ 'from' => ['pending'] , 'to' => 'failed' , ] , 'pay' => [ 'from' => ['pending'] , 'to' => 'paid' , ] , ] , ];
  • 26. $config = [ 'graph' => 'payment' , 'property_path' => 'state', 'states' => ['new','pending','failed','paid'] , 'transitions' => [ 'process' => [ 'from' => ['new'] , 'to' => 'pending' , ] , 'fail' => [ 'from' => ['pending'] , 'to' => 'failed' , ] , 'pay' => [ 'from' => ['pending'] , 'to' => 'paid' , ] , ] , ];
  • 27. $config = [ 'graph' => 'payment' , 'property_path' => 'state' , 'states' => ['new','pending','failed','paid'], 'transitions' => [ 'process' => [ 'from' => ['new'] , 'to' => 'pending' , ] , 'fail' => [ 'from' => ['pending'] , 'to' => 'failed' , ] , 'pay' => [ 'from' => ['pending'] , 'to' => 'paid' , ] , ] , ];
  • 29. Maintained by Symfony Flex support Work fl ow & state machine support Execution of external services with events XML / YAML / PHP support out-of-the-box Best documentation hands down
  • 30.
  • 31.
  • 32. $definitionBuilder = new DefinitionBuilder() ; $definition = $definitionBuilder->addPlaces(['new','pending','failed','paid'] ) ->addTransition(new Transition('process', 'new', 'pending') ) ->addTransition(new Transition('fail', [‘pending'], 'failed') ) ->addTransition(new Transition('pay', 'pending', 'paid') ) ->build( ) ; $singleState = true ; $property = 'state' ; $marking = new MethodMarkingStore($singleState, $property) ; $workflow = new Workflow($definition, $marking, null, 'payment');
  • 33. $definitionBuilder = new DefinitionBuilder() ; $definition = $definitionBuilder->addPlaces(['new','pending','failed','paid'] ) ->addTransition(new Transition('process', 'new', 'pending') ) ->addTransition(new Transition('fail', ['pending'], 'failed') ) ->addTransition(new Transition('pay', 'pending', 'paid') ) ->build( ) ; $singleState = true ; $property = 'state' ; $marking = new MethodMarkingStore($singleState, $property) ; $workflow = new Workflow($definition, $marking, null, 'payment');
  • 34. $definitionBuilder = new DefinitionBuilder() ; $definition = $definitionBuilder->addPlaces(['new','pending','failed','paid'] ) ->addTransition(new Transition('process', 'new', 'pending') ) ->addTransition(new Transition('fail', [‘pending'], 'failed') ) ->addTransition(new Transition('pay', 'pending', 'paid') ) ->build( ) ; $singleState = true ; $property = 'state' ; $marking = new MethodMarkingStore($singleState, $property) ; $workflow = new Workflow($definition, $marking, null, 'payment');
  • 36. Oldest and most popular implementation (in terms of stars) Least used implementation (in terms of daily installs according to packagist) Extendability with events & callbacks de fi nition Perhaps reached its EOL (https://github.com/yohang/Finite/issues/161) It is said to be little bit heavier implementation compared to Winzou
  • 37.
  • 38.
  • 40. final class Payment { public const NEW = 'new'; private string $state = self::NEW; public function getState(): string { return $this->state; } public function setState(string $state): void { $this->state = $state } }
  • 42. $payment = new Payment() ; $stateMachine = new StateMachine($payment, $config) ; $stateMachine->apply('process') ; $stateMachine->apply('fail');
  • 44. $payment = new Payment() ; $workflow->apply($payment, 'process') ; $workflow->apply($payment, 'fail');
  • 45.
  • 46.
  • 47. Th e end of chapter 2
  • 49.
  • 51. final class InventoryOperato r { public function __invoke(TransitionEvent $transitionEvent): voi d { $stateMachine = $transitionEvent->getStateMachine() ; /** @var Payment $payment * / $payment = $stateMachine->getObject() ; // Reduce inventory of bought product s } } $config = [ // .. . 'callbacks' => [ 'before' => [ 'reduce_amount' => [ 'on' => ['pay'] , 'do' => new InventoryOperator() , ] , ] , ] , ];
  • 52. final class InventoryOperato r { public function __invoke(TransitionEvent $transitionEvent): voi d { $stateMachine = $transitionEvent->getStateMachine() ; /** @var Payment $payment * / $payment = $stateMachine->getObject() ; // Reduce inventory of bought product s } } $config = [ // .. . 'callbacks' => [ 'before' => [ 'reduce_amount' => [ 'on' => ['pay'] , 'do' => new InventoryOperator() , ] , ] , ] , ];
  • 53. final class InventoryOperato r { public function __invoke(TransitionEvent $transitionEvent): voi d { $stateMachine = $transitionEvent->getStateMachine() ; /** @var Payment $payment * / $payment = $stateMachine->getObject() ; // Reduce inventory of bought product s } } $config = [ // .. . 'callbacks' => [ 'before' => [ 'reduce_amount' => [ 'on' => ['pay'] , 'do' => new InventoryOperator() , ] , ] , ] , ];
  • 54. Guard Before After Callbacks types * Same can be achieved with dispatched events
  • 55. class StateMachine implements StateMachineInterface { public function apply(/** */): void { // Guard callback if (!$this->can($transition)) { throw new SMException(); } // Before callback $this->setState('failed'); // After callback } }
  • 56. final class InventoryOperato r { public function __invoke(TransitionEvent $transitionEvent): voi d { $stateMachine = $transitionEvent->getStateMachine() ; /** @var Payment $payment * / $payment = $stateMachine->getObject() ; // Reduce inventory of bought product s } } $config = [ // .. . 'callbacks' => [ 'before' => [ 'reduce_amount' => [ 'on' => ['pay'] , 'do' => new InventoryOperator() , ] , ] , ] , ];
  • 57. On -> transition From -> state To -> state Callbacks types
  • 59. $dispatcher = new EventDispatcher() ; $dispatcher->addListener ( 'workflow.payment.enter.paid', new PaymentPaidListener( ) ) ; $workflow = new Workflow($definition, $marking, $dispatcher, 'payment'); final class PaymentPaidListener { public function __invoke(EnterEvent $event): void { // Reduce inventory of bought products } }
  • 60. $dispatcher = new EventDispatcher() ; $dispatcher->addListener ( 'workflow.payment.enter.paid', new PaymentPaidListener( ) ); $workflow = new Workflow($definition, $marking, $dispatcher, 'payment'); final class PaymentPaidListener { public function __invoke(EnterEvent $event): void { // Reduce inventory of bought products } }
  • 61. $dispatcher = new EventDispatcher() ; $dispatcher->addListener( 'workflow.payment.enter.paid', new PaymentPaidListener( ) ) ; $workflow = new Workflow($definition, $marking, $dispatcher, 'payment'); final class PaymentPaidListener { public function __invoke(EnterEvent $event): void { // Reduce inventory of bought products } }
  • 62. $dispatcher = new EventDispatcher() ; $dispatcher->addListener( 'workflow.payment.enter.paid', new PaymentPaidListener( ) ) ; $workflow = new Workflow($definition, $marking, $dispatcher, 'payment'); final class PaymentPaidListener { public function __invoke(EnterEvent $event): void { // Reduce inventory of bought products } }
  • 63. $dispatcher = new EventDispatcher() ; $dispatcher->addListener( 'workflow.payment.enter.paid', new PaymentPaidListener( ) ) ; $workflow = new Workflow($definition, $marking, $dispatcher, 'payment'); final class PaymentPaidListener { public function __invoke(EnterEvent $event): void { // Reduce inventory of bought products } }
  • 64. work fl ow.[place type] work fl ow.[work fl ow name].[place type] work fl ow.[work fl ow name].[place type].[place name] Actions
  • 65. leave -> current place enter -> which place(places) will be visited entered -> which place(places) were visited Types for places
  • 66. work fl ow.[transition type] work fl ow.[work fl ow name].[transition type] work fl ow.[work fl ow name].[transition type].[transition name] Actions
  • 67. guard -> possibility to validate transition transition -> which transition will be executed completed -> which transition was executed announce -> which transition are available now Types for transitions
  • 68. class Workflow implements WorkflowInterface { public function apply(/** */ ) { $this->leave(/** */) ; $this->transition(/** */); $this->enter(/** */) ; /** Making transition */ $this->markingStore->setMarking($payment, 'failed', $context) ; $this->entered(/** */) ; $this->completed(/** */) ; $this->announce(/** */) ; } }
  • 69.
  • 70.
  • 72. final class BlockAuthorizer { public function __invoke(): bool { return false; } } $config = [ /** ... * / 'callbacks' => [ /** ... * / 'guard' => [ 'guard-blocked' => [ 'to' => ['blocked'] , 'do' => new BlockedAuthorizer() , ] , ] , ] , ];
  • 74. final class BlockedGuardListener { public function __invoke(GuardEvent $event): void { $event->setBlocked(true); } } $dispatcher->addListener ( 'workflow.payment.guard.block' , new BlockedGuardListener( ) ) ;
  • 75.
  • 76. Th e end of chapter 3
  • 78. De fi ne possible states and relation between them Protect business rules (with guards) Trigger other services on transitions Ease to add new possible transitions Trigger other state changes as a reaction
  • 80.
  • 81. Why should you care?
  • 83. Business logic wired up in con fi guration fi les
  • 84. Describe problem with state machine but implement directly in code
  • 85. Possibility to destroy state of entities if state machine is omitted
  • 86.