I’d like to request the ability for Monitor scripts to be able to indicate whether they should be displayed in the context menus at the time the menu is shown, based on some contextual information. The script could define an (optional) callback function that would be passed contextual information about the entit(y/ies) that are being right-clicked, possibly as a dict. or a set of keyword arguments, and this callback would need to return True or False to indicate whether it should be displayed.
As some examples, for a Job script, some pieces of information that would be good to pass might be:
Number of selected jobs (or just a list of Job IDs)
Job state(s)
Job plugin(s)
Job user(s)?
For task scripts:
Job ID
Task ID(s)
Task state(s)
Task frame range(s)
For Slave scripts:
Slave name(s)
Machine name(s)
Slave State(s)
The idea is to pass along enough information that in most cases, the scripts’ callback functions generally wouldn’t have to call any API methods to decide whether they should be displayed (but could if they wanted to). Obviously Deadline already makes similar decisions about which menu items to display contextually based on selected items, and this would extend that functionality to user scripts.
We used to do something like this in Deadline 5 and earlier via an INI file that sat alongside the script. We removed this feature for Deadline 6 due to the performance implications because this information had to be queried during the right-click operation, before the context menu was displayed. This would result in a delay if there were lots of scripts, or if the repository was in a remote location. Having a callback in the script itself wouldn’t do anything to help the performance issues.
This would avoid any performance issues, because the contextual settings would be stored in the database. However, I’m not sure we could support all the types of information you’ve specified. Ones that would likely work include:
single selection or multi selection (would apply to all script types except Submission and General)
state of selected jobs, tasks, slaves, etc
plugin (jobs only)
For users, you can already control which scripts are visible for user groups, so you should be able to control it that way.
Thoughts?
In the meantime, you can check this information in the main function of the script, and popup an error message if the context isn’t valid. For example, our job right-click scripts to submit Quicktime jobs will show this popup if more than one job is selected.
Isn’t all the job information already available in the monitor’s cache? It could simply pass the cached job objects of the selected items to the callback function (or in the case of tasks/slaves, the appropriate data)
Sorry, I should have been more clear. The performance problem comes from calling the callback itself, not from the data that would be passed to it.
Deadline only caches a script (as well as its last write time) when the script is executed. The next time that script’s menu item is clicked on, we check if the last write time has changed, and then reload the script if it has. This doesn’t impact the performance of displaying the menu because it’s done when the menu item is clicked. Having a callback would affect performance though because it would need to be called before the menu is shown, and it would need to be called for every script that would appear in that menu.
So if you have 20 scripts in a remote repo, that’s going to result in quite a delay before the menu is displayed. Our rule of thumb is that we can’t go to disk to determine if a menu item should be displayed or not, and this goes against that policy.
I definitely agree. I find the fact that the scripts are exec’ed each time to be a bit strange, although I can see reasons for and against. In the longer-term, it would be great if there were ways to add scripts/callbacks that were actual entry points instead of files on disk.
With that in mind, maybe using a config file that gets cached would make more sense.
There’s still the problem of the initial loading of these config files though. That’s why I had thrown out the idea of adding more options to the Script Menu settings in the Repository Options so we wouldn’t have to load any files from disk.
But the Monitor already scans all kinds of files from the repository at startup (unless things have changed…). Would it really be that big of a deal to add in a one-time read of several more small files?
I know, but if we were considering going the route of a config file, it would have the same limitations.
Don’t forget that you can still check context when the script is executed and popup a message explaining the proper context to use it in. So the general settings like selection count, state, etc would get you most of the way there, but then any advanced checking would be done handled in the main function of the script.
Another option would be to pre-load all the scripts to ram, and poll for file changes periodically, instead of on right click.
That way you wouldn’t go to disk every time someone clicks and could call the callbacks as required.
The preload could still be slow if the repository is remote though.
The only files we load during startup is the icon files, and we’d like to keep it that way if at all possible since that alone can already slow down the launch of the Monitor.
Would it be possible to add in proper Python methods or hooks for building menu items then? The current scripts system is sort of designed for the most basic forms of customization, without requiring much actual development knowledge. For developers, it would be great to have closer access to the UI construction (e.g. construction callbacks with access to the actual QMenus being built to allow for new actions to be added, construction of menu items with actual callables to fire, etc.).
We’d like to get there at some point (in addition to allowing users to create custom panels), but it’s not something that is currently on the roadmap.
However, adding support for basic contextual information in the Script Menu settings in the Repository Options should be something we can support in the near term (if you think it’s still useful).
Hmm… I use a remote monitor, and it takes about ~3 minutes for it to open, of which loading the icons is only 265ms:
2015-02-26 12:10:19: BEGIN - VCPRO1014\ScanlineVfx_user
2015-02-26 12:10:19: Deadline Monitor 6.2 [v6.2.1.49 R (6fcf10b83)]
2015-02-26 12:10:19: Time to initialize: 468.000 ms
2015-02-26 12:10:25: Time to connect to Repository: 4.633 s
2015-02-26 12:10:26: Time to check user account: 62.000 ms
2015-02-26 12:10:26: Time to purge old logs: 16.000 ms 2015-02-26 12:10:26: Time to synchronize plugin icons: 265.000 ms
2015-02-26 12:12:59: Time to initialize main window: 2.561 m
2015-02-26 12:13:00: Main Window shown
2015-02-26 12:13:00: Time to show main window: 218.000 ms
I guess it depends on how fast the connection is and your dataset size, but in my case, loading the remote files was 0.16% of the total load time.
For the plugin files, what we do is sync them locally if they don’t exist, so once they’re synced locally, it’s much faster to load. This is acceptable because the look of the icons has so impact on the functionality of the Monitor. If icons get updated and you want the latest ones, you can use Tools -> Synchronize Scripts and Plugin Icons to pull down the latest.
I don’t think we would want the same behavior for monitor scripts though, since that would mean that users would have to manually synch the scripts locally to get any updates.
I think the long time to initialize the main window is due to the additional python modules you guys have Deadline loading on startup, which I imagine are also on a remote server.
I was referring to the things I had mentioned earlier, like selection count, state, job plugin, etc.