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
[Workflow] Dynamic workflow feature proposal #26561
Comments
Hello @yann-eugone First, thanks for your very interest of the workflow composant, and thanks for this very detailed RFC Then, There is something very important with dynamic workflow: How to you treat the marking of the subject this the associated place is not present in the workflow anymore ? I mean, let's say I die suddenly (it's not planned don't worry), Many pull request could be in the place That's why Symfony does not support dynamics workflow. Dynamic workflow are hard because so much thing should be take care off. So you have to do it by yourself. I'm sorry about that. Finally, I will try to answer your question:
If you can have a generic "dynamics" dentition builder, I will be glad to merge it
So basically you need a workflow to be added in the registry to be able to get it in twig. So I think The best option is to compose the default Registry. You will inject the your DynamicWorkfowBuilder in it. If the asked workflow does not exist (checked via the (decorated) workflow registry), you will use the DynamicWorkfowBuilder. Finally, thanks to a compiler pass, you will decorated the default registry. It's quite easy and you do not need to use the EventDispatcher
You can simply listen on |
Of course there is drawbacks, of course you have to deal with these use cases, and I don't believe Symfony should take care about it. This issue is more about "what was the hard part of my work integrating with the component".
OK, I'll open a dedicated pull request for this, you'll tell me.
Tell me if i'm wrong, if I decorate the Registry, i'll have something like this class MyRegistry
{
public function __construct(Registry $registry) { //... }
} We will need at least an interface, so MyRegistry can be injected in other services as a valid workflow registry. Do you agree ?
I agree, I could subscribe to a more generic event to add my guard listeners, but still i need the workflow name, which is dynamic (let say it is composed with a static string and the subject id). So I need to register to the most generic event class MyGuardListener
{
public function onTransition(GuardEvent $event)
{
if (!preg_match('{^pull_request_[0-9]+$}', $event->getWorkflowName())) {
return false;
}
if (!preg_match('{^[a-z0-9]+_approve_review$}', $event->getTransition()->getName())) {
return false;
}
// todo guard
}
} Don't you think it is a bit dangerous ? |
Additionally
As I said, there is several ways to do it. But if I prefer the event listener, it's because of the extensibility it add to the process. The other advantage I see is that it looks like compliant with Symfony will : being fastest as possible by lazy loading almost everything. |
You are right, we don't have an interface for that :/
No, you can use that safely But you can also use the
why my solution is even more faster because there a no event dispatcher and everything is lazy loaded. |
I'm not looking for a way to do the job in my project. I already did, and I'm okay with the implementation. Reading your response seems to me : "I'm not interested in this feature".
When I say dangerous I mean : the event listener will be called for each transition of each workflow.
From a performance point of view, yes, but it is less flexible. |
Maybe it's just me, but this is the last thing I would like to see in my code. In the situation you described I would advise you to do this:
I have 4 workflows tied together like this, works like a charm. |
Absolutely not. But as I explained, Dynamic workflow are very hard. More over I agree with @Padam87 Finally, ATM, I failed to see what you want to add to Symfony. I'm always open to new contributions. Even more if many people could use theses new features. If it's only about adding a What other things do you want to add? |
I agree that there are many different solutions to a single problem. Looks like you are describing some kind of a sub-workflow system. I already tried something like this, and it was ok. But when you really need that you workflow is a single piece, you have no choice. (for instance, i needed it in one piece, because the workflow is dumped to a png file which is attached to the entity, each time a transition is processed : so the end user can see where the entity is) The changes I want to introduce are the one I talked about in the initial content. To be more concise (maybe it was too much text, after all) :
|
Thanks for the clarification. For now, I have no strong advice:
So I let the community and other core member decide if we want to accept a pull-request about it. |
Thanks for pinging @lyrixx. Firstly @yann-eugone thanks for this RFC, this is well explained and very nice to read. I kind of agree about dynamic workflow, but being able to have tools to build them is a good thing for the component, we should really be careful when documenting this feature and giving advices on how to do things. This feature should be really well tested and we have to add a good DX, because if something is wrong even if the workflow is dynamic, it should be pointed out (if we can). So I'm +1 on this feature, but as I said, we should really be careful on how we explain this feature to other people. |
You are welcome @Simperfit . I knew it was something difficult, so I tried to give as much details as possible. Yes, I did already most of the things, in a project I developped. I totally agree to say that this feature could be disturbing if you are not at ease with the static workflows. |
@yann-eugone let people imagine something is very dangerous as the each one's heads think and imagine something different from the others. I've understood what you are trying to accomplish and you had a lot of useful advices. More, you said the code is already existent in your project. What about put part of it in our hands so we can see it? The code speaks much better than words... |
@Aerendir |
To simplify the usage of the Twig APIs, maybe we could simply make them accept
Events are dispatched to the main event dispatcher service, for which you can register additional event listeners if you want. So you could register your own instance of the GuardListener dynamically with a dedicated config instead of trying to alter the config of the listener instance registered for static workflows. |
Twig was just an example. As a developer I really expect that any other integration will work with both static and dynamic workflow (for instance I'm working on a Sonata extension).
Once again, I've found a way to the job on my own. And this is pretty much what I did (even if I was not satisfied to copy the whole listener logic in my own source code). |
I am not sure I understand the actual issues that you had. Maybe you can elaborate these things a bit more:
There is nothing preventing you from manually creating a
The default registry is just a service. So you could add your dynamically created workflow to the registry right after creating it. How would that change with your idea?
The same here, you can use the service at runtime and call the method that adds a new listener. What needs to be changed here? |
Why do you need to copy the logic ? If you instantiate and register a listener dynmically, you can totally configure it in the constructor in the existing class. Why did you need to copy the logic ? |
btw, if you register the listener dynamically at the same time than building the workflow, it also solves the issue about the regex matching on the name, as you know the exact name at that point. Having a statically registered listener able to manage rules for dynamic workflows will indeed force you to use the very generic events and then perform filtering before applying the logic. I doubt the component can do anything for you in this case (as your statically registered listener does not know the workflow name). |
Hello @yann-eugone I'm sorry, But I'm going to close this issue because we have answered all your questions. But feel free to reply or to open a PR if you want to contribute to Symfony. Thanks again for this discussion ;) |
I understand that you are not interested in this feature proposal. Sorry for the waste of time. |
@yann-eugone personally i think it is a pitty if you don't create a PR or share your code on packagist in a bundle linked to this issue. if people search for dynamic workflow component they will find your code even if it might not get merged into the official code |
For the record, I'm not against such PR. I'm just a bit afraid of implications |
I recently faced some difficulties with the workflow component.
I've spent some time trying to figure out what was missing, so my goal was covered out of the box.
I'm posting this issue because I really want some advices before I open a pull request.
Static workflows
There is my problem : workflows are static.
Let's clarify this sentence : a workflow is registered within the configuration, so you write YAML to define places and transitions.
When the container is dumped, it contains an ended list of available workflow, each one covered with a support strategy and a definition.
This is a problem to me, because I assume that in real life examples, nothing is static.
Real life example
Let's take an example (THE (almost) unique example you can find in every blog post) : a pull request.
This is one of the common structure I've found on the different blog post. But, this is not
true
!A better structure could be :
When a pull request is
opened
, some automated tests are triggered, and some responsible teammates's approval are requested, in the same time.These feedback usually come from some configuration, which depends on the repository itself.
So your model type :
PullRequest
; is under a workflow. But the definition depends on eachRepository
(an other model).This is the problem I've been facing with : how to work these "dynamic" workflows.
More specific questions
How to build workflow and definition ?
Workflow
andDefinition
are pretty simple objects. Still, we miss a class to help creating instances of these classes.I've been looking at
DefinitionBuilder
but I think this is not enough.I feel myself more comfortable with a config tree (like the one in the framework config), so you can create workflow like this :
Basically, this will create (and return) a
Workflow
object (containing aDefinition
) which is usable as is.How and when to add it to the registry ?
This is to me the hardest part of the this feature.
I really want my "dynamic" workflows to be retrieved from the
Registry
, so I can useTwig
functions and other bridges.I've found several ways to do it, each method has pros and cons.
My favorite one is using an event listener to register a missing workflow.
Workflow registry has to be updated to ensure this feature :
The registry is asked for an unknown workflow, it triggers an event on which your application can subscribe.
Your listener is asked to create the missing workflow. It can use the factory (we talked about), and add the created workflow to the event.
How to guard transitions ?
The
approve
ordisapprove
review transitions are performed by authenticated users.I expect that that only
fabpot
can applyfabpot_approve_review
andfabpot_disapprove_review
.So I need to be able to configure a guard expression for these transition.
Something like :
Then I need to configure and register
GuardListener
for my transitions events.This listener has to be modified, so it accept configuration at runtime.
Something like :
So in my workflow factory I can configure it like this :
The text was updated successfully, but these errors were encountered: