Wrestling Tasks
I think the built-in and pluggable task manager in MT is a great bit of functionality, but I've been learning the hard way that its API in MT4 is a bit broken particularly when it comes to backwards compatibility with MT3.
Feeds.App RC1 users reported that the task that updates the feeds cache was throwing an error when they tried it with MT4. The system complained that a task could not be registered without an ID -- a new attribute in MT4. So this broke any MT3 tasks like the one in Feeds.App at that time.
When adapting Feeds.App to work under version 4 and handling issues like these, I also learned that MT did not take into account the perfectly legal practice of subclassing MT::Task as I had done rather then use a HASH to configure a generic object.
I made the ugly patch of creating a hash from the methods in my subclass methods. That seemed to work, but I was mistaken according to testers.
The way I had been registering my task in MT3 wasn't being recognized (here I might have been coloring outside the lines a bit too much) that I had to takes steps to use the registry and wrap the MT3 specific registration in a "if version number is less then 4" condition. I couldn't just use what I had in my MT3 style task subclass. MT4 didn't like that one bit. I had to refactor my code into a separate class that didn't subclass MT::Task. (The joys of multi-version support!) That seemed to work, but I found something interesting that wasn't documented (as of this writing) and an annoying quirk.
tasks => {
'feedsapp_update' => {
label => 'Feeds.App Update',
frequency => 'sub { require MT::Plugin::FeedsApp::Tasks; MT::Plugin::FeedsApp::Tasks::update_cache_frequency(@_) }',
handler => 'MT::Plugin::FeedsApp::Tasks::update_cache',
},
},
Not "pictured" in the example (as of this writing), Frequency can be a code or handler -- well of sort. For reasons I don't quite understand the frequency handler (like in a YAML file) must be an anonymous subroutine in order for MT to convert it to a CODEREF. Here is the code from MT::Task::init:
if ( $freq =~ m/^\s*sub\s*\{/s ) {
}
My guess is that this is MT's way of determining what is a value (86400 aka once a day) rather then the name of a method such as MT::Foo::method. Seems plausible, but there are less intrusive and less verbose ways of doing this that could have been applied.
The easiest and best route would have been to test for any characters that are not 0 through 9 since frequency must be expressed in (whole) seconds.
if ( $freq =~ m/[^0-9]/s ) {
...
}
Let's assume the integer only option is not available -- checking a string for a double colon and no whitespace is pretty good though not perfect.
if ( $freq =~ m/^[^\S]+::[^\S]+$/s ) {
...
}
It's not not as perfect in my opinion because the reguglar expression is a bit more complex and there is a remote chance of a value that is not meant to be interpreted as a handler name matching this pattern.
The problem here with both is that this precludes the use of an anonymous subroutine. That's actually fine by me though I know others would disagree. In order to appease the masses some slightly more complex logic would be required:
if ( $freq =~ m/^\s*sub\s*\{/s ) {
# handler evaluating anon subroutine code.
} elsif ( $freq =~ m/^[^\S]+::[^\S]+$/s {
# do handler to CODEREF
}
If this were applied my registry entry becomes less verbose and cleaner which is the type of thing that makes me happy.
tasks => {
'feedsapp_update' => {
label => 'Feeds.App Update',
frequency => 'MT::Plugin::FeedsApp::Tasks::update_cache_frequency',
handler => 'MT::Plugin::FeedsApp::Tasks::update_cache',
},
},

There are no comments yet. You could be the first!