mirror of
https://github.com/go-gitea/gitea.git
synced 2026-03-15 04:17:01 -05:00
Refactor gitea internal event queues to use external library #8133
Closed
opened 2025-11-02 07:54:55 -06:00 by GiteaMirror
·
6 comments
No Branch/Tag Specified
main
release/v1.25
release/v1.24
release/v1.23
release/v1.22
release/v1.21
release/v1.20
release/v1.19
release/v1.18
release/v1.17
release/v1.16
release/v1.15
release/v1.14
release/v1.13
release/v1.12
release/v1.11
release/v1.10
release/v1.9
release/v1.8
v1.25.3
v1.25.2
v1.25.1
v1.25.0
v1.24.7
v1.25.0-rc0
v1.26.0-dev
v1.24.6
v1.24.5
v1.24.4
v1.24.3
v1.24.2
v1.24.1
v1.24.0
v1.23.8
v1.24.0-rc0
v1.25.0-dev
v1.23.7
v1.23.6
v1.23.5
v1.23.4
v1.23.3
v1.23.2
v1.23.1
v1.23.0
v1.23.0-rc0
v1.24.0-dev
v1.22.6
v1.22.5
v1.22.4
v1.22.3
v1.22.2
v1.22.1
v1.22.0
v1.23.0-dev
v1.22.0-rc1
v1.21.11
v1.22.0-rc0
v1.21.10
v1.21.9
v1.21.8
v1.21.7
v1.21.6
v1.21.5
v1.21.4
v1.21.3
v1.21.2
v1.20.6
v1.21.1
v1.21.0
v1.21.0-rc2
v1.21.0-rc1
v1.20.5
v1.22.0-dev
v1.21.0-rc0
v1.20.4
v1.20.3
v1.20.2
v1.20.1
v1.20.0
v1.19.4
v1.21.0-dev
v1.20.0-rc2
v1.20.0-rc1
v1.20.0-rc0
v1.19.3
v1.19.2
v1.19.1
v1.19.0
v1.19.0-rc1
v1.20.0-dev
v1.19.0-rc0
v1.18.5
v1.18.4
v1.18.3
v1.18.2
v1.18.1
v1.18.0
v1.17.4
v1.18.0-rc1
v1.19.0-dev
v1.18.0-rc0
v1.17.3
v1.17.2
v1.17.1
v1.17.0
v1.17.0-rc2
v1.16.9
v1.17.0-rc1
v1.18.0-dev
v1.16.8
v1.16.7
v1.16.6
v1.16.5
v1.16.4
v1.16.3
v1.16.2
v1.16.1
v1.16.0
v1.15.11
v1.17.0-dev
v1.16.0-rc1
v1.15.10
v1.15.9
v1.15.8
v1.15.7
v1.15.6
v1.15.5
v1.15.4
v1.15.3
v1.15.2
v1.15.1
v1.14.7
v1.15.0
v1.15.0-rc3
v1.14.6
v1.15.0-rc2
v1.14.5
v1.16.0-dev
v1.15.0-rc1
v1.14.4
v1.14.3
v1.14.2
v1.14.1
v1.14.0
v1.13.7
v1.14.0-rc2
v1.13.6
v1.13.5
v1.14.0-rc1
v1.15.0-dev
v1.13.4
v1.13.3
v1.13.2
v1.13.1
v1.13.0
v1.12.6
v1.13.0-rc2
v1.14.0-dev
v1.13.0-rc1
v1.12.5
v1.12.4
v1.12.3
v1.12.2
v1.12.1
v1.11.8
v1.12.0
v1.11.7
v1.12.0-rc2
v1.11.6
v1.12.0-rc1
v1.13.0-dev
v1.11.5
v1.11.4
v1.11.3
v1.10.6
v1.12.0-dev
v1.11.2
v1.10.5
v1.11.1
v1.10.4
v1.11.0
v1.11.0-rc2
v1.10.3
v1.11.0-rc1
v1.10.2
v1.10.1
v1.10.0
v1.9.6
v1.9.5
v1.10.0-rc2
v1.11.0-dev
v1.10.0-rc1
v1.9.4
v1.9.3
v1.9.2
v1.9.1
v1.9.0
v1.9.0-rc2
v1.10.0-dev
v1.9.0-rc1
v1.8.3
v1.8.2
v1.8.1
v1.8.0
v1.8.0-rc3
v1.7.6
v1.8.0-rc2
v1.7.5
v1.8.0-rc1
v1.9.0-dev
v1.7.4
v1.7.3
v1.7.2
v1.7.1
v1.7.0
v1.7.0-rc3
v1.6.4
v1.7.0-rc2
v1.6.3
v1.7.0-rc1
v1.7.0-dev
v1.6.2
v1.6.1
v1.6.0
v1.6.0-rc2
v1.5.3
v1.6.0-rc1
v1.6.0-dev
v1.5.2
v1.5.1
v1.5.0
v1.5.0-rc2
v1.5.0-rc1
v1.5.0-dev
v1.4.3
v1.4.2
v1.4.1
v1.4.0
v1.4.0-rc3
v1.4.0-rc2
v1.3.3
v1.4.0-rc1
v1.3.2
v1.3.1
v1.3.0
v1.3.0-rc2
v1.3.0-rc1
v1.2.3
v1.2.2
v1.2.1
v1.2.0
v1.2.0-rc3
v1.2.0-rc2
v1.1.4
v1.2.0-rc1
v1.1.3
v1.1.2
v1.1.1
v1.1.0
v1.0.2
v1.0.1
v1.0.0
v0.9.99
Labels
Clear labels
$20
$250
$50
$500
backport/done
💎 Bounty
docs-update-needed
good first issue
hacktoberfest
issue/bounty
issue/confirmed
issue/critical
issue/duplicate
issue/needs-feedback
issue/not-a-bug
issue/regression
issue/stale
issue/workaround
lgtm/need 2
modifies/api
modifies/translation
outdated/backport/v1.18
outdated/theme/markdown
outdated/theme/timetracker
performance/bigrepo
performance/cpu
performance/memory
performance/speed
pr/breaking
proposal/accepted
proposal/rejected
pr/wip
pull-request
reviewed/wontfix
💰 Rewarded
skip-changelog
status/blocked
topic/accessibility
topic/api
topic/authentication
topic/build
topic/code-linting
topic/commit-signing
topic/content-rendering
topic/deployment
topic/distribution
topic/federation
topic/gitea-actions
topic/issues
topic/lfs
topic/mobile
topic/moderation
topic/packages
topic/pr
topic/projects
topic/repo
topic/repo-migration
topic/security
topic/theme
topic/ui
topic/ui-interaction
topic/ux
topic/webhooks
topic/wiki
type/bug
type/deprecation
type/docs
type/enhancement
type/feature
type/miscellaneous
type/proposal
type/question
type/refactoring
type/summary
type/testing
type/upstream
Mirrored from GitHub Pull Request
No Label
type/refactoring
Milestone
No items
No Milestone
Projects
Clear projects
No project
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/gitea#8133
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @lafriks on GitHub (Nov 18, 2021).
Maybe we could use watermill library to replace (at least parts of) our queue code https://github.com/ThreeDotsLabs/watermill
@lunny commented on GitHub (Nov 19, 2021):
There are something we have to consider:
@lafriks commented on GitHub (Nov 19, 2021):
@zeripath commented on GitHub (Nov 21, 2021):
I think we need specific reasons as to what is hoped to be gained and what's missing from queues.
It's one thing to suggest a drop-in work queue replacement. It's quite another to suggest completely refactoring.
From glancing at the repo this library is mostly focused on pubsub message queues. I think there's definitely something in being able to use pubsub for querying our work queues - but that is something different from what our work queues do.
For a start it really is worth noting that pub sub absolutely blocks a Redis connection - so you need one Redis connection per queue. At present we avoid this. This would limit the number of queues we could use.
It may well be that we could be inspired by watermill or even integrate it into our queue infrastructure but it doesn't seem suitable at first glance as a replacement. Instead this would require a either a complete refactor to use pure MQs or the creation of a separate MQ.
Now how could we use a pure MQ as a unique queue? Well we would have to either use a Redis/LevelDB Set on work retrieval or at message creation - or use some kind of DB locking on the records. That's a major refactor - potentially one that's worth it but it would likely mean that the simple API we currently have for the queues would go away. (Essentially our unique queue API as it stands is
Pushto the user and to the handler writer simply provide a handler.)The alternative of adding a side channel event MQ with pubsub would allow us to keep our current queue infrastructure but allow the worker queue readers to be informed by messages on the event queue. I've been toying with the idea of a creating a broadcast queue for cluster events etc and a general MQ which could use pubsub to inform work queues but it seems likely that such a queue would be permanently alerted so wouldn't necessarily be particularly performant.
However I think you need to tell us why you think you'd want to do this and what you hope to gain.
We also need to have confidence that this project will still be there in 4, 2 - even 1 - year's time. Too many of Gitea's dependencies are in a poorly maintained state and we should be thinking much more carefully before adding any more.
@roblaszczak commented on GitHub (Nov 22, 2021):
Hey @lafriks @zeripath, author of Watermill here!
If you are happy to explore deeper if Watermill may fit your use case I'm happy to assist. I'm also happy to look deeper to this RedisStream implementation (as it's not an official one). If the implementation quality would be good enough we could ask the author if it could be included in the list of official implementations.
Do you have any high-level overview of how you are using Redis? In general core library is pretty flexible on Pub/Sub model and it depends a lot on the specific implementation of Pub/Sub.
@zeripath commented on GitHub (Nov 22, 2021):
@roblaszczak thanks for getting in touch.
We're not currently using pubsub as the queues aren't really message queues - although they could be used that way and the intention of the queue infrastructure was to move us over time to a place where we could use event queues.
We have essentially two types of work queue - non-unique queues which use a Redis keyed List using RPush, LPop and LLen, and unique queues which wrap a Redis Set around the List. (using SAdd, SRem and SIsMember). The Redis lists are simply polled instead of using pubsub as that blocks redis connections and we're avoiding opening too many connections at present. (This is not ideal but appears to be functional.) We have a leveldb implementation which we use in a similar way.
I would propose that instead of using windmill directly immediately that we would simply create a windmill queue provider (at least in the first instance.) That would significantly minimize the size of PR to add this functionality and would make things a lot simpler. We'd need to think carefully about configuration and how it would be displayed to the user.
Allowing the non-unique work queues to use a windmill provider would be simple - create an event each time there is a push to a queue and wrap the message with an envelope of which work queue it was sent to. We could easily create a worker for each message type which could be one of our currently created dynamic worker pools or, if windmill supports its own we could let windmill do that itself.
Now, the unique work queues would be a bit more difficult - but I guess we could have a unique work queue handle their sets somewhere else and either have the unique message handler deal with the set or send a message back to a specific thing listening to remove things from the set.
(Presumably windmill has some lifecycle controls or allows subscribers to register and deregister on their own accord to allow us to correctly and safely manage shutdown of Gitea by shutting down workers independent of the brokers.)
One final consideration is that we may need some way of querying if the work queue is empty and to flush the work queue. The things that get pushed on to the work queue may unfortunately change between versions so it would be useful to flush them before shutting down for upgrade etc. I'm not sure if windmill has that functionality at a glance. If not we'd need to manage counts of items in each work queue separate from the messages similar to the sets above.
I think it would be quite simple to create a suitable redisstream provider and subscriber ourselves if the mentioned project wasn't ready - we'd likely need to do some of the work ourselves anyway. So the lack of a redis subscriber is not a problem. We'd also need to adjust our modules/nosql/manager_redis.go to give us a new client for each subscriber because of the above blocking.
@wxiaoguang commented on GitHub (May 9, 2023):
The queue has been completely rewritten.
The only blocker is the Gitea's specialized "unique queue" (actually, it doesn't make sense)
So I think this issue could be closed, the new code is much easier to maintain.