Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[POC] [Workflow] Made StateMachine supports only single state marking #20491

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

HeahDude
Copy link
Contributor

@HeahDude HeahDude commented Nov 11, 2016

Q A
Branch? master
Bug fix? yes
New feature? yes
BC breaks? yes
Deprecations? no
Tests pass? yes
Fixed tickets #19629
License MIT
Doc PR TODO

Since StateMachine cannot be in one place at the time it does not make sense to allow multiple marking. Actually we default to the right SingleStateMarkingStore, but we can't prevent it with any interface.

This PR makes Marking and MarkingStore abstract so any implementation can use the component mechanisms by defining a marking strategy using Marking constants in the MarkingStore constructor.

Hence we need two marking classes SingleStateMarking and MultipleStateMarking so every internal piece of the workflow knows how to behave regarding marking.

Also we only need one PropertyAccessMarkingStore which use the same decency for its logic but can handle both strategies.

Most of the abstract class are public and can easily be overridden.

Wdyt?

@stof
Copy link
Member

stof commented Nov 12, 2016

This prevents using any other custom implementation of the MarkingStore return astate with a single place, so -1 for that.

@xabbuh
Copy link
Member

xabbuh commented Nov 12, 2016

Maybe we could think about introducing dedicated marker interfaces for marking stores that support or do not support multiple states at the same time.

@HeahDude
Copy link
Contributor Author

Ok I think I've got an idea.

Status: needs work

@HeahDude HeahDude changed the title [Workflow] Made StateMachine supports only SingleStateMarkingStore [POC] [Workflow] Made StateMachine supports only SingleStateMarkingStore Nov 12, 2016
@HeahDude HeahDude changed the title [POC] [Workflow] Made StateMachine supports only SingleStateMarkingStore [POC] [Workflow] Made StateMachine supports only single state marking Nov 12, 2016
@HeahDude
Copy link
Contributor Author

Ok I've updated the PR and the description, I'm finishing some tests, but this is ready to review as POC.

Maybe it will inspire someone for something better :)

* @param object $subject A subject
* @param SingleStateMarking $marking
*
* @return SingleStateMarking The marking
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setters have no reason to return the marking (the return value is ignored anyway)

return;
}

$this->places[$place] = $this->places[$place] + 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+= 1 or ++

@@ -30,6 +30,14 @@ public function add(Workflow $workflow, $className)
$this->workflows[] = array($workflow, $className);
}

/**
* @param $subject
* @param null $workflowName
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong phpdoc

if ($place) {
$this->mark($place);
} else {
$this->place = array();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless as the property is already initialized

@stof
Copy link
Member

stof commented Nov 12, 2016

@lyrixx could you have a look at this one ?

@HeahDude
Copy link
Contributor Author

HeahDude commented Nov 12, 2016

@stof thank you for your comments, they're now addressed, I might have fixed another bug in 2289c55 EDIT: and c4599fc add a new feature for multiple tokens by place.

This can be very powerful to handle votes, or deal with weighted places in events.

I'm gonna add an event by default for workflow to guard if more than 1. Wdyt?

@HeahDude
Copy link
Contributor Author

Reviewing my code on GH, I think it might be worth having Marking and MarkingStore abstract and get rid of the interfaces.

@HeahDude HeahDude force-pushed the fix-state-machine-constructor branch 2 times, most recently from 39ae224 to 08dbffb Compare November 13, 2016 18:54
@HeahDude HeahDude force-pushed the fix-state-machine-constructor branch from 08dbffb to 7c47114 Compare November 13, 2016 18:57
@HeahDude
Copy link
Contributor Author

I've updated this PR so it has only one clean commit and a better description.

Status: needs review

@HeahDude
Copy link
Contributor Author

Failures unrelated.

class SingleStateMarking extends Marking
{
/**
* @param mixed $place A scalar as only place or null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be string|null

public function __construct($place = null)
{
if (null !== $place && !is_scalar($place)) {
throw new InvalidArgumentException(sprintf('"%s" instances only accept scalar or null as single place, but got "%s".', __CLASS__, is_object($place) ? get_class($place) : gettype($place)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this safeguard is actually needed.

throw new InvalidArgumentException(sprintf('"%s" instances only accept scalar or null as single place, but got "%s".', __CLASS__, is_object($place) ? get_class($place) : gettype($place)));
}

if ($place) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be if(null !== $place) {

} elseif (isset($workflow['marking_store']['service'])) {
$markingStoreDefinition = new Reference($workflow['marking_store']['service']);

$markingStrategy = 'state_machine' === $type ? 'single_state' : $workflow['marking_store']['type'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$markingStrategy = 'state_machine' === $type ? Marking::STRATEGY_SINGLE_STATE : Marking::STRATEGY_MULTIPLE_STATE;?

*/
public function __construct($expectedClass, $marking)
{
$this->message = sprintf('Marking must be an instance of "%", but got "%"', $expectedClass, is_object($marking) ? get_class($marking) : gettype($marking));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parent::__construct(...)

{
private $places = array();
const STRATEGY_SINGLE_STATE = 'single_state';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These constants belong to the MarkingStore class imo.

*/
class Marking
abstract class Marking
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this class is really needed.. why not a pointer interface and 2 final implementations instead?

@lyrixx
Copy link
Member

lyrixx commented Nov 14, 2016

@ro0NL Hi. Thanks for your review, But this is a POC. So please don't comment about CS / PHPDocs etc... @HeahDude will fix all those tiny details later if the PR is accepted.

@lyrixx
Copy link
Member

lyrixx commented Nov 14, 2016

Hello @HeahDude

I understand why you made this PR and I agree a pitfall may exist for newcomers.

But I don't like your current implementation:

1/ There are too many code added, it adds too many complexity
2/ You renamed place into state, this is wrong

It could be solved in the full stack framework in a simpler way: just check the framework type with the type marking store type.
It will not solve all errors since it's possible to use a custom service for the marking store. But I think if people implement a custom marking store, they know what they are doing.

I don't implemented what I said, because it's not perfect and because the default configuration is error proof.

If you can find a much simpler solution to implement this kind of validation in the composant, I will be glad to merge it. but for now I'm -1

@HeahDude
Copy link
Contributor Author

@lyrixx I understand. Thank you for your feedback, I'll try to look at it again with this in mind :)

@HeahDude
Copy link
Contributor Author

I'll come with something else :)

Status: needs work

@nicolas-grekas nicolas-grekas added this to the 3.x milestone Dec 6, 2016
@lyrixx
Copy link
Member

lyrixx commented Dec 13, 2016

I'm sorry, but I have to close this PR as the current implementation is too complex
(I have talked with @HeahDude IRL about this PR)

@lyrixx lyrixx closed this Dec 13, 2016
@nicolas-grekas nicolas-grekas modified the milestones: 3.x, 3.3 Mar 24, 2017
@HeahDude HeahDude deleted the fix-state-machine-constructor branch November 24, 2018 13:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants