Problem/Motivation
Many initiatives on d.o focus around various issue queue queries. Critical/major bugs, issue tags, specific status values, components, sort orders, combos of the above, etc. Usually there are handbook pages, meta issues, etc, trying to track progress, which provide various links to issue queues (e.g. the Bug Smash Initiative).
We'd love to see summary counts of these queries, so we could watch how the totals are changing over time.
Proposed resolution
- Add JS that detects any issue queue search links (
<a href="*/project/issue/search/*">...</a>
). - AJAX request to an endpoint with issue queue aware caching.
- Append
(total: $count)
to the link text.
Remaining tasks
Decide if this is feasible.Debate the appropriate syntax to use.Is there some prior art we should re-use instead of inventing our own thing?- Should we just scan for
<a href=".*/project/issue/*">...</a>
, detect it's an issue queue link, and do the magic automatically with no special syntax? - YES Something like the bespoke thing above?Other?
- Implement the feature:
- Will need site-wide setting for which view to use, since there could be custom views for just this, Search API views (d.o), etc.
- Regexp to parse / understand the syntax we decide.
- Caching.
- Load/invoke the view.
- Append the result total.
- Tests
- Review
- RTBC
- Commit
- Deploy to d.o and configure (probably needs a separate issue in the infra queue).
User interface changes
API changes
Data model changes
Release notes snippet
Original report by @dww
We already have the [#xyz]
text filter to embed a link to individual issues, which expands the title, uses the current status to colorize the link, adds title text with the status, and crosses out closed status values.
Let's have a syntax that lets you easily embed specific issue queue views links in text. It'll render as the appropriate link to the issue queue, but most importantly, it would use the result summary (from #3151026: Add results summary to header of all default issue queue views) as part of what gets displayed.
We'd add a text filter that understands the syntax, loads the appropriate view object, add the arguments, execute the query, and get the count. Since it's a text filter, the result would be cached until the next time the node it appeared in was edited, so we wouldn't necessarily have a horrific performance cost (right?). ;)
Proposed resolution
Something like this. Totally weird syntax, *not* the actual proposal yet:
[:issue-queue:"Link text goes here":"MACHINE_NAME?GET_ARGS":]
e.g.:
[:issue-queue:"Most stale major and critical bugs":"drupal?status%5B0%5D=Open&priorities%5B0%5D=400&version%5B0%5D=any_9.&version%5B1%5D=any_8.&order=last_comment_timestamp&sort=asc":]
You would see (approximately):
Comment | File | Size | Author |
---|---|---|---|
#39 | 3151163-39.patch | 2.74 KB | dww |
#27 | 3151163-27.patch | 8.84 KB | larowlan |
#27 | 3151163-interdiff-27.txt | 3.89 KB | larowlan |
#16 | 3151163.patch | 8.07 KB | larowlan |
Comments
Comment #2
drummOn syntax - I’d recommend the full URL. It is easy to copy/paste, and less ways for people to get it wrong.
Yes, this could be used to create particularly heavy issue pages, especially with count queries often being slower, and the cache could mostly save us.
Hard to say if this would be a dealbreaker. Drupal.org’s field cache clears, where text formatting is effectively cached, are currently not good. Maybe an additional cache of issue queue URL → total, so it has some decoupling; although that’s even more complexity.
The numbers not updating in real time would be a bit annoying.
Comment #3
drummI’ve always thought some for of saved searches would be great to have, but have never gotten into figuring out what that would actually look like, or if there are any contrib modules to help. #2090661: Homebox Block: Issue Search With Saved Values is the closest issue I can find right now.
Something like a project could save a search, and the summaries of those are all on a project-specific page. And/or people saving searches and having their user-specific page summarizing them.
Comment #4
jungleMaybe, to develop a contributed module is more flexible tracking anything on-demand on any Drupal instances.
The feature of updating numbers in realtime is critical I think. https://contribkanban.com/ does not update in realtime, so it's less valuable to me.
Comment #5
dwwRe: #2: My concern on just using the full URL is that this result counter thing is potentially expensive, and I didn't want us to automatically convert any issue queue link we see. I thought folks should have to go out of their way to someone opt-in to that behavior. If we decide we don't care about the performance implications, I agree that auto-conversion of anything that matches an issue queue link would be easier for everyone to use.
Note that my proposed syntax is already (mostly) a copy/paste of the URL, since the MACHINE_NAME part is already in the issue queue links in question. E.g.:
You just copy from "drupal" onward and you're set.
Re: caching -- I'm reluctant to introduce a separate bespoke cache for this. a) More complexity b) Totals would be even more stale. Would rather there was an easy way to refresh all the totals on a page -- if it's just the filter cache, all you have to do is edit the page and it'll re-compute all the referenced totals.
Re: #3: Yeah, I thought so, too. ;) I was searching for prior issues on the topic of "saved searches" but came up blank. There are probably older issues floating around, but I doubt they're talking about this specific implementation that can be embedded anywhere on the site, so I figured it was safe to open a fresh issue about it when inspiration struck late last night...
Re: #4:
A) Interesting idea on trying to do this as a generic, stand-alone thing. However, how would it know what view(s) to use for any given link? If it's generic, then the author has to specify the view as part of the embed code, which seems really clumsy and yucky. If it's something like "parse all links, do a route match to figure out if it's a link pointing to a view, if so make sure the view either shows all results or uses a full pager, if so load the view, set the args, run the query, etc." that seems really complicated and expensive. I was hoping that keeping it project_issue-specific would simplify how it works and how you embed them.
B) The more "real-time" the updating happens, the more expensive this gets. I don't think it can be truly "real-time", or we'd have to invalidate every one of these links on every issue update (which probably happen at least every minute, if not more frequently than that). That'd effectively make it not cached at all, which would probably add a noticeable strain on our infra. I think something like the filter cache is about right -- the totals are computed once, then not updated at all until the page containing the links is edited again. Issue updates would only cause any new queries if the issue itself references issue queue links...
Comment #6
larowlanThis would negate the need for the work I was going to do in #3142774: I want a drupal.org development site for issue queue statistics - so plus one.
In terms of caching, could we not do something like so:
I realise this won't help us with processed text caching though.
So that probably means it might be a placeholder and some JS that did a round trip to the server to dynamically replace the values using ajax. We could even tally up all the placeholders in the page and do it in a single request, like history module does in Drupal 8. That way the rendered output of the formatter is cacheable and we just put a 4 hour or something expiry on the entries in the bin, so its at most 4 hours old.
Given I'm planning to build something for #3142774: I want a drupal.org development site for issue queue statistics would you prefer I work on this instead?
Comment #7
dwwIf you can work on this on your sandbox, great! Yes, please.
The JS / AJAX replacement sounds great, but if/how does it degrade?
Maybe #4 could still work? A "Views Summary Link" module that provides the text filter, settings, AJAX callback, JS...
Perhaps admins could define shortcuts for which view a given slug uses, or you can spell out the full machine name if you like/need (replacing the "issue-queue" part of my bogus syntax).
If it's too complicated to do generically, I'm ok with the original project_issue-only proposal.
Yay!
-Derek
Comment #8
larowlanOk, so this sounds like something worth working on, put perhaps a thumbs-up from @drumm on the approach before I dig in would give me confidence about it being accepted
Comment #9
larowlanIt is just a link to the listing page.
Comment #10
dwwGreat. Regular link with a class that the JS finds to append the count. Love it.
Thoughts on issue-specific vs. letting this work for any view and the rest of #7?
Thanks!
-Derek
Comment #11
larowlanI was thinking we would enhance any link that had a href starting with
https://www.drupal.org/project/issues/search/{project}
so that would be limited to just the project-issue view I thinkComment #12
drummThe AJAX solution sounds like a good plan.
For all new JS on Drupal.org, I’ve only been using jQuery when absolutely necessary, like extending vertical tabs JS. I’ve also switched from piling code into common JS files like
js/project-issue.js
to separate ones, since we have HTTP/2. For new features, I’m trying out ES6 syntax, like https://git.drupalcode.org/project/drupalorg/-/commit/a645172b0e56c93420..., we’ll see how that goes. The Fetch API has certainly been nicer than XMLHttpRequest.Comment #13
larowlanYep, that's consistent with our workflow at work, so that's great to know - will stick with that approach
Comment #14
dwwFantastic! So happy to see this taking shape.
This is now a more accurate title for the proposed feature, right? Updated summary accordingly.
Thanks!!
-Derek
Comment #15
larowlanYep, thanks - will work on this today
Comment #16
larowlanThis is in place on the issue stats sandbox - sample page here https://issuestat-drupal.dev.devdrupal.org/node/3142429
Feels weird to use modern Javascript features with PHP 5 array syntax 😝
Its a stand-alone module, tried to protect against nefarious stuff.
Would have liked to use GET so we could cache stuff, but the request could easily be too big.
Comment #17
larowlanthis can go, was using a filter originally
some of this is d.o specific - this means this probably belongs on d.o only rather than in project_issue
Comment #18
dwwMostly looks great, thanks! Super excited to see this coming to life!!
So we have to have a project machine name in the link? So e.g. links to issue tags that span projects won't work, huh?
That's because we can't invalidate the cache in any reasonable way for those?
Project Issue Counts
Wants a period.
Probably enough of an edge case that we don't care, but issues can move from project to project, and this wouldn't notice that fact to invalidate the count for both the old and new projects...
Input filter?
what's \_project_issue_count()?
Do we actually need to do all this? Can't we just hand the params to set_exposed_input() and lets Views worry about invalid things?
continue not return?
Comment #19
dwwRe: #16
At first, I was confused by this. "But isn't the view itself relying on GET? How could this be too big?" Then I realized this is a single request for all the links on a page, so yeah. Now I get it. ;)
Comment #20
dwwx-posts, sorry. Re: #17.2: I think your fallback stuff should work well. At most we could have a setting to define which view/display to use for this. But I don't think this needs to be d.o-specific. I'm still in favor of putting it in project_issue (either directly or a sub module).
Comment #21
dwwCouple more thoughts:
Drat, I guess that means we can't use this for links to searches with specific sort orders. E.g. on the Bug Smash Initiative page, we have "Most stale major and critical bugs (sorted by least recently updated)" and the like. Not sure how to have those work without screwing up click-sort (which we obviously don't want). Can we only exclude /sort/ if we're inside a
<th>
or something?I notice we're using
project_load()
.project
is a dependency ofproject_issue
already, but maybe we should explicitly depend onproject
, too? /shrugComment #22
catchSomething missing from the current issue search that would be useful here is a date filter. So that we could get counts of issues closed and opened in the last month/year.
Comment #23
dwwDon't get me started on views exposed date filters. ;) I guess this is D7, so maybe it's easier. But here's (part of) the patches section of my composer.json for a real D8 site trying to use them:
Comment #24
xjmI'd want date filtering too, despite the pain. Date filtering is also one of the top "missing features" for core mentoring and part of what requires mentors to have to manually triage the Novice queue (because super-stale issues do not make good novice targets).
Comment #25
dwwOkay, then let's move date filtering to a new issue. That's out of scope here. 😜 If/when we get that working in the regular views UI, it'll either be no change, or a fairly small change, to this code.
Thanks,
-Derek
Comment #26
xjmOh yeah, totally not saying we should do it in the first patch. :) I think there might be an existing issue.
Comment #27
larowlan18.1/5/6/7/9 done
18.2 yep correct
18.3/4 not relevant anymore
18.8 never trust user input :) - there's no form token/build ID being passed here so I think we owe it to views to make sure this stuff is clean before we hand it along
21.1 fixed
21.2 not relevant anymore
Agree re date filters, but yeah out of scope - let's open another issue for that.
Updated https://issuestat-drupal.dev.devdrupal.org/node/3142429 to add an example of sorting.
Comment #29
dwwLooks fantastic, thanks! Did some more local testing, and didn't find any trouble. All feedback addressed. Committed and pushed to project_issue 7.x-2.x branch. Huzzah! 🎉
Moving to RTBC and tagging for d.o deployment (since I no longer have access to do that myself).
Thanks again, this is going to be fabulous when it's live. 😀
Comment #30
dwwComment #31
dwwThis is in @drumm's court now.
Thanks,
-Derek
Comment #32
drumm+ $view->preview($display, [$project->nid]);
I believe this will render the whole view, when we only really want the count query results. Is there a way to do that with the Views API? Loading up to 50 issues per-linked-view will be relatively slow when there is a cache miss.
Comment #33
drummI think something like this might work:
If I understand Views internals, which I often don’t, I think that will just execute the query and count query. Doing only the count query would be ideal, but the regular results query isn’t the worst-performing thing.
Comment #34
dwwI guess we could try with
execute_display()
instead ofpreview()
. I believe that would help.If we want to really dig into the internals of the Views API, we could try loading up the pager handler, and invoking
execute_count_query()
directly on that.Comment #35
dwwMessed with this a bit just now. Couldn't get it working by directly trying to initialize the pager and invoking
execute_count_query()
. :( But this seems to work, usingexecute()
notpreview()
. It looks like this isn't actually loading and rendering things. @drumm, is this sufficient?In other news, I realized none of this code works if you have a site installed in a subdir. ;)
This regexp assumes Drupal is installed at /
This one is more friendly to subdirs.
But this won't work, either. Not sure the right way to solve this. Perhaps there needs to be a config value pushed down with the JS for the URL to POST to?
Comment #36
larowlanWe have base path available in Drupal settings, it should use that. I'm sans laptop until Tuesday but will pick it up then
Comment #37
dwwOh yeah, good point. This patch fixes that.
Meanwhile, oh crap, here's another problem:
https://www.drupal.org/project/issues/count
;)
Whoops. So this patch also moves the callback to live at project/autocomplete/* namespace (like other Project* AJAX callbacks) since "autocomplete" is already a reserved word.
Comment #38
drummOne nitpick -
@\/project\/issues\/search\/(?<machine_name>[a-z0-9_]+)$@
doesn’t need the slashes escaped, since the regular expression delimiter is@
.I’ll also want to check how this handles full-text searches, where we have the full count query disabled by using Views’s lite pager. Those queries can be expensive in some cases. It might not be a problem with caching, but still will be good to know how it is handled.
Comment #39
dwwRe: #38 - Good call. Fixed here. Tested locally and all working well.
Any final objections / improvements, or can we deploy this?
Thanks!
-Derek
Comment #41
drummThis has been deployed: Project issue issues
I found & corrected one other small issue: https://git.drupalcode.org/project/project_issue/commit/e071281
This does count issues for full text searches. We can wait and see if that’s a practical problem in production. If it happens to be, we can see about altering that somewhere in drupalorg, like we do for switching to the lite pager.
Comment #42
drummMy demo in the last issue didn’t fire because https://git.drupalcode.org/project/project_issue/-/blob/7.x-2.x/js/proje... matches the “Advanced search” pages only.
Here is a link that should be working: Advanced search for project issue issues
Comment #43
drummAnd it requires some filter, it matches
\?
in the URL.This should work this time
Comment #44
drummThis is also causing some 500s I’m trying to track down:
Comment #46
drummAn example of what was causing that 500 is https://www.drupal.org/node/1086584#comment-11026855, the “blank screen” link. Since #3089291: Group issue version “series” by branch instead of API compatibility, that filter redirects former values to the new equivalent. Since we can’t call
drupal_goto()
in this context anyway, I blocked off that section of code to not run for these requests.I went ahead and removed that too, since I am deploying that fix.
Comment #47
drummThose followups are now deployed, and our error rate has dropped back down to approximately zero.
https://www.drupal.org/node/1086584#comment-11026855 does replace to “blank screen [null issues]” now. That link has invalid choices for the the version parameter when not redirected. I don’t see that making any other noise, so it is okay as-is. Followups might include:
Comment #48
tim.plunkettThis is really cool! But can be very noisy on some pages, and is downright disheartening when the Core queue is linked ;)
Opened #3157292: Allow issue counts in issue search links to be targeted by userstyles
Comment #50
larowlanFollow up is here #3157318: Add ability to filter by created/update date to issue advanced search
Comment #51
volegerSome things I noticed on one of the user dashboard blocks "Contributor links":
Previous issues count looks redundant now.
"Novice issues" have no counter attached in comparison to other links.
Comment #52
larowlanI am so happy that at least the numbers are the same 😎
But agree a bit redundant
Comment #53
dwwRe: #51: Thanks, good point! Moved that to #3157596: Remove now redundant counts on 'Contributor links' dashboard block since that block comes from drupalorg_project module. Let's continue that discussion over there.
Cheers,
-Derek