-
Notifications
You must be signed in to change notification settings - Fork 11
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
31 event trigger #664
31 event trigger #664
Conversation
bf3b14a
to
e947e37
Compare
This should be ready for an initial review now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Submitting feedback in parts.
I'm going to skip most phpdoc related ones, as they are indicated on the CI. But noted the ones which might not have appeared.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more comments.
Thanks for making the changes @matthewhilton, I'm still a bit on the fence regarding whether or not it should appear under the reader list or trigger list.
In its current state, it can't act like a typical trigger-connector step. I think the sweet spot would be to tweak the handling of the dataflow iterator to allow for trigger steps that are "flows" to act like readers. This is because you wouldn't have a step that comes before this.
ref: #663
classes/local/step/reader_event.php
Outdated
if (!$this->enginestep->engine->isdryrun) { | ||
event_processor::consume_event($input->id); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does a dry run event data get passed to the run at the moment? I scanned the class and didn't see a form field for this sort of data, and below it seems to be referenced.
$variables->set('event', $input->eventdata);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assumed that dry runs would pull the event data just like any other run would. Although that might be a bad assumption, i'll look into it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tested the dry run and the get_iterator
is called to get the event data and it is passed to the execute
function just as like any other run.
When I go to dry-run there is no form that pops up - is this a feature that steps can implement? I'm not too familiar with ti
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no such feature currently. It would be nice, for the interface to display / prompt the user for an input when required (or stop until the input has been supplied).
A similar issue had been created here, but this is for the initial trigger (form trigger)
#443
If / once that has been implemented, it could potentially be expanded to other steps and allow for gating.
For testing purposes, perhaps the data could be set up in the step itself? And would only be used for testing (e.g. dry runs) due to the absense of a form feature.
Though, at the same time it might be good to make a generic field to hold dry-run test data that is used if certain conditions were checked. But I think this is somewhat scope creep, and should be implemented in another issue.
I'm leaning towards adding a generically named field to hold the test (event) data for now, and building on that concept later down the track.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm leaning towards adding a generically named field to hold the test (event) data for now, and building on that concept later down the track.
I think this should probably be implemented later since to me it seems a bit complex and not necessary at the moment:
- Different events have different structures, so would we store a test event for every event type? What about installed plugin events?
- If I wanted to dry-run for e.g. a
course_viewed
event, it would probably have to load the test data and then extra form field for e.g. what user, what course id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Different events have different structures, so would we store a test event for every event type? What about installed plugin events?
By default it will be empty and that either passes through no data or fails. Users can define their own test data which would be based on what they expect it to look like.
If I wanted to dry-run for e.g. a course_viewed event, it would probably have to load the test data and then extra form field for e.g. what user, what course id
Yes, and those things could come from expressions as well, or hard-coded based on what the tester wants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good if we could add some unit tests as well. This should work and be testable for the 'run immediately' type of execution, and can verify the event data comes through as expected.
Thanks @keevan for the review 😄 . Unit tests are definietely coming just wanted to settle down the whole structure of the new code first
Could you give some pointers about how this would be achieved ? |
Test case ideas:
|
ef3be93
to
04522d9
Compare
I added a new method to the base_step: moodle-tool_dataflows/classes/local/step/base_step.php Lines 642 to 651 in 04522d9
And overrode it in the reader step moodle-tool_dataflows/classes/local/step/reader_step.php Lines 42 to 50 in 04522d9
And so instead of checking moodle-tool_dataflows/classes/local/execution/iterators/dataflow_iterator.php Lines 133 to 140 in 04522d9
This is equivalent to the code before; readers will not pull the next. However, this now means the new Furthermore, I styled the trigger as blue to indicate to the user 'This is a trigger, but its also kinda a reader' since ultimately it is a reader with a bit of trigger'ry stuff sprinkled on top I thought about going the other way and making this new Moodle event trigger based on the Would like some feedback on ^^ though. |
04522d9
to
8394948
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything looks mostly good. As discussed internally regarding the colour choices, I think keep it the same as the normal trigger step. It will ultimately head towards that direction after the future refactor.
I'll wait until you've added the rest of the things you plan to add such as those tests before taking another look.
Also I'm curious, have you tried testing if you can reference the event data using ${{ record.eventdata.courseid }}
based on your example in VARIABLES.md
, as that should by default work.
One test case I'd like to cover as well, is one where on an event, you read some SQL data based on the data from the event and write it somewhere. It'd be interesting to inspect the shape of the $input that gets passed through.
2559a4b
to
635d810
Compare
Was running into #639 causing the unit tests on 3.5 and 3.6 to fail. I implemented a check that if the function exists, use it, otherwise just queue it. Apart from just copying the entire logic of the function in OR splitting the MOODLE_XX_STABLE branches, I think this is the best solution. moodle-tool_dataflows/classes/task/process_dataflow_ad_hoc.php Lines 57 to 62 in 635d810
|
532eb10
to
f33cf70
Compare
This currently isn't allowed since the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more comments. Otherwise it looks like it's in a good shape. Once those are cleaned up I'll do another round of functional testing.
f33cf70
to
f3ea414
Compare
05fefba
to
1d30817
Compare
db/upgrade.php
Outdated
@@ -234,5 +234,28 @@ function xmldb_tool_dataflows_upgrade($oldversion) { | |||
upgrade_plugin_savepoint(true, 2022091600, 'tool', 'dataflows'); | |||
} | |||
|
|||
if ($oldversion < 2022100601) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to match the one defined in version.php, and would be better if it was bumped by date instead of a micro bump. I had issues adding the table and noticed the zero was meant to be a 2. :')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah I thought i fixed this... will fix it again 😆
Functional testing seems OK. I encountered some issues. Using the example workflow in this PR |
I noticed something similar too, but I thought it was the result of the debugging writer. Maybe I might add output buffer catching and pass this to the debugging output instead when using this option. |
Also some things discussed internally:
|
1d30817
to
7cb01ea
Compare
When adhoc tasks are created these are only recording the dataflow ID to run - no event data is included in the adhoc task itself, this is loaded from the DB when it is run based on the trigger's step id. And once it is loaded into a dataflow, the record is deleted. The trigger step itself does not really care at all how it is run, you could queue 500 events and 1000 adhoc tasks to process them and it wouldn't care, after all the events are processed the remaining tasks would just have empty iterators. I think I may move the event consuming from when the execute() is called to when the iterator is created. Then I will add a lock around this to ensure parallel tasks don't access the queue at the same time otherwise it might be possible for multiple parallel tasks to read from the queue twice. |
Reorganised the code that handles the execution of the dataflows to enable outside classes to access it (such as the event trigger)
Not all steps will define a nextruntime. So now it is only logged if it is present
When determining if the iterator should pull the next, instead of checking the group, we check now the function has_producing_iterator. This allows the group to be independent.
7cb01ea
to
ff7c613
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few small comments. Going through functional testing now.
Adds event reader step along with an extra helper class event_processor to handle triggering dataflows from Moodle events
ff7c613
to
923345c
Compare
923345c
to
74be99d
Compare
Issues fixed: 1 - Comma required after last value in array declaration 10 - Each line in an array declaration must end in a comma 1 - Expected a blank line before function 1 - Expected a space after FUNCTION keyword 1 - Expected a space after SWITCH keyword 1 - Multi-line array contains a single value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Merging in for now and we'll tweak if we encounter any issues
PR to add event triggers.
What has been added
New event trigger
This event trigger works the following:
event_reader
steps are configured to listen to this event.tool_dataflows_events
table4.1. Execute the dataflow immediately
4.2. Create an adhoc task to execute the dataflow
4.3. Wait until the next CRON call to dataflow to run it.
event
variable available to later steps.What has been changed
nextruntime
is now optional (since now event triggered dataflows don't have a nextruntime like cron ones do)Things left to do:
Some areas I would like comment / feedback / ideas on
Closes issues
Closes #31
Closes #665
Closes #666
Example dataflow
See example dataflow below (captures course viewed event, then calls course_get_contents webservice)
Just replaced the user with the admin user on your site