This commit makes the `contact_url` in the /about page behave as an absolute URL instead of a relative one if it doesn't explicitly start with a slash or a protocol. This prevents situation where, e.g., `www.example.com` is specified in the setting and the contact URL anchor tag ends up with a `href` that navigates to `<site address>/www.example.com` instead of just `www.example.com`. We prevent this by adding 2 leading slashes `//` to `contact_url` which makes the `href` resolves to the specified `contact_url` using the same protocol as the current site's.
Internal topic: t/143907.
This commit adds the `add_request_rate_limiter` plugin API which allows plugins to add custom rate limiters on top of the default rate limiters which requests by a user's id or the request's IP address.
Example to add a rate limiter that rate limits all requests from Googlebot under the same rate limit bucket:
```
add_request_rate_limiter(
identifier: :country,
key: ->(request) { "country/#{DiscourseIpInfo.get(request.ip)[:country]}" },
activate_when: ->(request) { DiscourseIpInfo.get(request.ip)[:country].present? },
)
```
When lurking on a Discourse as anonymous, if the sidebar is enabled, and a section contains only secondary links that are not visible to anonymous users, we should not display the "more..." button.
Otherwise it feels broken because clicking on it does nothing, since there are no "visible" links to be shown.
Internal ref t/144716
NOTE: I wasn't able to reproduce locally, so that's my best guess as to what happens based on the production error logs.
It's also the reason why I haven't changed/added any tests...
Earlier today, we started seeing a growing number of errors in the `register_presence_channel_prefix("chat-reply")` handler of the chat plugin.
It was all coming from a Discourse where they make a heavy use of chat channels. They create and **delete** category channels regularly.
If a user has a thread in one of the channels that just got deleted, the client application might not be aware (just yet), asks the server to be connected to the "presence" bus of that channel, and BOOOM.
The following [line](fa0ad0306c/plugins/chat/plugin.rb (L325)) explodes because `chat_channel` is `nil`
```ruby
config.allowed_group_ids = chat_channel.allowed_group_ids
```
And why is `chat_channel` `nil`? Because when we [do](fa0ad0306c/plugins/chat/plugin.rb (L319))
```ruby
chat_channel = Chat::Thread.find_by!(id: thread_id, channel_id: channel_id).channel
```
The thread is still in the database, but the associated channel has been deleted.
A proper fix would most likely be to delete all the `Chat::Thread` associated to a deleted `Chat::Channel` but this might have more technical & business implications.
* wip: return full name in /notifications.json
* DEV: test for full name
* DEV: add test for enable_names=true
* DEV: add notification6, cleanup
* DEV: fix tests
This PR involves cleaning up the codebase from my (@keegangeorge's) todos.
In particular:
- Remove Form Template related todos (these are no longer in the roadmap)
- Remove old left-over AI summarization related code after moving to AI (https://github.com/discourse/discourse-ai/pull/658)
- Update one form template related spec
Followup 203f93bcaf
This commit makes sure the background for all the admin
site settings filters (including the filter input and
override checkbox) is consistent no matter what the theme,
as it currently changes based on theme.
* Split `shutdown` into two separate methods for better control:
- `shutdown` - signals threads to stop accepting new work
- `wait_for_termination` - waits for threads to finish (with optional timeout)
* Add tracking of busy threads via `@busy_threads` Set
* Make idle_time parameter optional with 30-second default
* Improve thread spawning logic:
- Spawn initial thread immediately when work is posted
- Spawn additional threads when all threads are busy and work is queued
* Fix race condition in work distribution
* Add busy thread count to stats output
* Add test coverage for zero min_threads configuration
This commit makes the ThreadPool more reliable, easier to use, and adds
better visibility into its internal state.
---------
Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
This commit introduces a new ThreadPool class that provides efficient worker
thread management for background tasks. Key features include:
- Dynamic scaling from min to max threads based on workload
- Proper database connection management in multisite setup
- Graceful shutdown with task completion
- Robust error handling and logging
- FIFO task processing with a managed queue
- Configurable idle timeout for worker threads
The implementation is thoroughly tested, including stress tests, error
scenarios, and multisite compatibility.
The security fix in 15b43a2 also introduced some unrelated refactoring to the file, which seems to be causing issues in some environments. This commit reverts the refactoring, and applies the security fix to each block individually.
This update adds a ✨ _new_ `<PostList />` component, along with it's child components (`<PostListItem/>` and `<PostListItemDetails />`). This new generic component can be used to show a list of posts.
It can be used like so:
```js
/**
* A component that renders a list of posts
*
* @component PostList
*
* @args {Array<Object>} posts - The array of post objects to display
* @args {Function} fetchMorePosts - A function that fetches more posts. Must return a Promise that resolves to an array of new posts.
* @args {String} emptyText (optional) - Custom text to display when there are no posts
* @args {String|Array} additionalItemClasses (optional) - Additional classes to add to each post list item
* @args {String} titleAriaLabel (optional) - Custom Aria label for the post title
*
*/
```
```hbs
<PostList
@posts={{this.posts}}
@fetchMorePosts={{this.loadMorePosts}}
@emptyText={{i18n "custom_identifier.empty"}}
@additionalItemClasses="custom-class"
/>
```