* Bump prepackage Zoom plugin version to 1.9.0
* Bump prepackage GitLab plugin version to 1.10.0
* fixed zoom version
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
* Adds the capability to retrieve a property field by name
Allows to retrieve a property field by name and groupID. As the name
is only unique within the context of a group, and we can have multiple
fields with the same name in the store, for this method the groupID is
directly included in the query instead of being an optional field.
* Adds the targetID parameter to correctly filter fields
* Ensure the method only retrieves non-deleted fields
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
A recent change to the enterprise cluster code introduced a change to the enterprise API interface. GetClusterInfos() can now return an error. This commit introduces code to handle that error.
On page load, we load ALL channels and channel members from all teams.
But then, on team_switch, we would again load channels and channel
members from that team. This was redundant and mainly kept
because previously the websocket events were considered unreliable.
Now with reliable websockets, and client-side pings, we can detect
broken connections faster and recover without loss.
Additionally, the getAllChannelMembers call would page through
all responses on the client side. This was inefficient and incur
extra latency. To optimize for this, we introduce server-side
streaming of the full response if page is set to -1.
This optimizes the intial response as well.
https://mattermost.atlassian.net/browse/MM-56906
```release-note
Optimize team switch operation by removing calls to get channels
and channel members.
```
Co-authored-by: Mattermost Build <build@mattermost.com>
We switch to using iterators introduced in Go 1.23
to make iteration alloc-free and fast. And since
element removal is allowed while iterating a map,
this also means we don't need to even copy the slice
any more.
While here, we also address the comment https://github.com/mattermost/mattermost/pull/30178#discussion_r1954862151.
I have simply gone back to using []string as the map
entry rather than a type alias or a redirection with
a struct.
https://mattermost.atlassian.net/browse/MM-63130
```release-note
NONE
```
* Changed back nil to len
```release-note
NONE
```
* fixing unused assignment
```release-note
NONE
```
* add benchmark
```
goos: linux
goarch: amd64
pkg: github.com/mattermost/mattermost/server/v8/channels/app/platform
cpu: Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz
│ old.txt │ new.txt │
│ sec/op │ sec/op vs base │
HubConnIndexIterator/2_users-8 93.53n ± 1% 38.09n ± 1% -59.27% (p=0.000 n=10)
HubConnIndexIterator/3_users-8 106.30n ± 0% 38.41n ± 1% -63.86% (p=0.000 n=10)
HubConnIndexIterator/4_users-8 111.30n ± 1% 38.66n ± 1% -65.27% (p=0.000 n=10)
geomean 103.4n 38.39n -62.89%
│ old.txt │ new.txt │
│ B/op │ B/op vs base │
HubConnIndexIterator/2_users-8 16.00 ± 0% 24.00 ± 0% +50.00% (p=0.000 n=10)
HubConnIndexIterator/3_users-8 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹
HubConnIndexIterator/4_users-8 32.00 ± 0% 24.00 ± 0% -25.00% (p=0.000 n=10)
geomean 23.08 24.00 +4.00%
¹ all samples are equal
│ old.txt │ new.txt │
│ allocs/op │ allocs/op vs base │
HubConnIndexIterator/2_users-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹
HubConnIndexIterator/3_users-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹
HubConnIndexIterator/4_users-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹
geomean 1.000 1.000 +0.00%
¹ all samples are equal
```
```release-note
NONE
```
* ForChannel test as well
```release-note
NONE
```
* review comments
```release-note
NONE
```
* fix lint errors
```release-note
NONE
```
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
For our MySQL customers, we have discovered that the query is not
able to choose the right plan by itself without adequate hints.
This is only for MySQL as we have confirmed from multiple customers
that Postgres takes the right index idx_sidebarcategories_userid_teamid
for the sidebarCategories table. And if it doesn't, then a VACUUM ANALYZE
fixes it.
But for MySQL, we have to do two things:
- Pass an index hint to let it use idx_sidebarcategories_userid_teamid.
- Pass an optimizer hint to materialize the sub-query. This is used
to materialize the doesNotHaveSidebarChannel sub-query into a temporary
table, letting MySQL reuse the contents of the table for further processing
in the parent sections of the query.
I have confirmed both locally and in the customer environment
that it gives a clear benefit.
*LOCAL*
OLD:
```
| -> Nested loop antijoin (cost=2889.85 rows=19767) (actual time=3.355..38.033 rows=15 loops=1)
-> Nested loop inner join (cost=66.65 rows=110) (actual time=0.410..1.689 rows=220 loops=1)
-> Filter: ((Channels.DeleteAt = 0) and (Channels.`Type` in ('O','P'))) (cost=25.25 rows=110) (actual time=0.394..0.886 rows=220 loops=1)
-> Index lookup on Channels using idx_channels_team_id_display_name (TeamId='team01'), with index condition: (Channels.Id is not null) (cost=25.25 rows=220) (actual time=0.389..0.793 rows=220 loops=1)
-> Single-row covering index lookup on ChannelMembers using PRIMARY (ChannelId=Channels.Id, UserId='user000') (cost=0.28 rows=1) (actual time=0.003..0.003 rows=1 loops=220)
-> Nested loop inner join (cost=4967.50 rows=180) (actual time=0.165..0.165 rows=1 loops=220)
-> Covering index lookup on SidebarChannels using PRIMARY (ChannelId=Channels.Id) (cost=7.86 rows=180) (actual time=0.055..0.062 rows=13 loops=220)
-> Filter: ((SidebarCategories.TeamId = 'team01') and (SidebarCategories.UserId = 'user000')) (cost=44.93 rows=1) (actual time=0.008..0.008 rows=0 loops=2881)
-> Single-row index lookup on SidebarCategories using PRIMARY (Id=SidebarChannels.CategoryId) (cost=44.93 rows=1) (actual time=0.006..0.006 rows=1 loops=2881)
|
```
NEW:
```
| -> Nested loop antijoin (cost=5879.73 rows=58021) (actual time=1.544..3.135 rows=15 loops=1)
-> Nested loop inner join (cost=66.65 rows=110) (actual time=0.421..1.778 rows=220 loops=1)
-> Filter: ((Channels.DeleteAt = 0) and (Channels.`Type` in ('O','P'))) (cost=25.25 rows=110) (actual time=0.405..0.945 rows=220 loops=1)
-> Index lookup on Channels using idx_channels_team_id_display_name (TeamId='team01'), with index condition: (Channels.Id is not null) (cost=25.25 rows=220) (actual time=0.400..0.859 rows=220 loops=1)
-> Single-row covering index lookup on ChannelMembers using PRIMARY (ChannelId=Channels.Id, UserId='user000') (cost=0.28 rows=1) (actual time=0.003..0.004 rows=1 loops=220)
-> Single-row index lookup on <subquery2> using <auto_distinct_key> (ChannelId=Channels.Id) (cost=130.37..130.37 rows=1) (actual time=0.006..0.006 rows=1 loops=220)
-> Materialize with deduplication (cost=130.35..130.35 rows=527) (actual time=1.118..1.118 rows=205 loops=1)
-> Filter: (SidebarChannels.ChannelId is not null) (cost=77.61 rows=527) (actual time=0.059..0.851 rows=523 loops=1)
-> Nested loop inner join (cost=77.61 rows=527) (actual time=0.058..0.786 rows=523 loops=1)
-> Covering index lookup on SidebarCategories using idx_sidebarcategories_userid_teamid (UserId='user000', TeamId='team01') (cost=2.81 rows=15) (actual time=0.025..0.031 rows=15 loops=1)
-> Covering index lookup on SidebarChannels using idx_sidebarchannels_categoryid (CategoryId=SidebarCategories.Id) (cost=1.70 rows=35) (actual time=0.032..0.046 rows=35 loops=15)
```
Performance improvement from 38ms to 3ms.
*CUSTOMER ENV* (with sensitive data wiped off)
OLD:
```
| -> Sort: channels.DisplayName (actual time=512..512 rows=5 loops=1)
-> Stream results (cost=3.28 rows=1.44) (actual time=223..512 rows=5 loops=1)
-> Nested loop antijoin (cost=3.28 rows=1.44) (actual time=223..512 rows=5 loops=1)
-> Nested loop inner join (cost=3.02 rows=0.3) (actual time=0.025..0.0878 rows=5 loops=1)
-> Covering index lookup on ChannelMembers using idx_channelmembers_user_id_channel_id_last_viewed_at (UserId='') (cost=0.916 rows=6) (actual time=0.0146..0.023 rows=6 loops=1)
-> Filter: ((channels.DeleteAt = 0) and (channels.TeamId = '') and (channels.`Type` in ('O','P'))) (cost=0.251 rows=0.05) (actual time=0.00999..0.0102 rows=0.833 loops=6)
-> Single-row index lookup on Channels using PRIMARY (Id=channelmembers.ChannelId) (cost=0.251 rows=1) (actual time=0.00778..0.00785 rows=1 loops=6)
-> Nested loop inner join (cost=2.85 rows=4.81) (actual time=102..102 rows=0 loops=5)
-> Covering index lookup on SidebarChannels using PRIMARY (ChannelId=channelmembers.ChannelId) (cost=2.01 rows=4.81) (actual time=0.0125..13.8 rows=24134 loops=5)
-> Filter: ((sidebarcategories.TeamId = '') and (sidebarcategories.UserId = '')) (cost=1.54 rows=1) (actual time=0.00359..0.00359 rows=0 loops=120671)
-> Single-row index lookup on SidebarCategories using PRIMARY (Id=sidebarchannels.CategoryId) (cost=1.54 rows=1) (actual time=0.00316..0.00319 rows=1 loops=120671)
```
NEW:
```
Here is the output
| -> Sort: channels.DisplayName (actual time=0.12..0.12 rows=5 loops=1)
-> Stream results (cost=3.45 rows=4.01) (actual time=0.0797..0.11 rows=5 loops=1)
-> Nested loop antijoin (cost=3.45 rows=4.01) (actual time=0.0769..0.106 rows=5 loops=1)
-> Nested loop inner join (cost=3.02 rows=0.3) (actual time=0.0291..0.0555 rows=5 loops=1)
-> Covering index lookup on ChannelMembers using idx_channelmembers_user_id_channel_id_last_viewed_at (UserId='') (cost=0.916 rows=6) (actual time=0.0145..0.0162 rows=6 loops=1)
-> Filter: ((channels.DeleteAt = 0) and (channels.TeamId = '') and (channels.`Type` in ('O','P'))) (cost=0.251 rows=0.05) (actual time=0.00611..0.00619 rows=0.833 loops=6)
-> Single-row index lookup on Channels using PRIMARY (Id=channelmembers.ChannelId) (cost=0.251 rows=1) (actual time=0.0053..0.00534 rows=1 loops=6)
-> Single-row index lookup on <subquery2> using <auto_distinct_key> (ChannelId=channelmembers.ChannelId) (cost=7.01..7.01 rows=1) (actual time=0.00956..0.00956 rows=0 loops=5)
-> Materialize with deduplication (cost=7..7 rows=13.4) (actual time=0.0451..0.0451 rows=0 loops=1)
-> Filter: (sidebarchannels.ChannelId is not null) (cost=5.66 rows=13.4) (actual time=0.0441..0.0441 rows=0 loops=1)
-> Nested loop inner join (cost=5.66 rows=13.4) (actual time=0.0439..0.0439 rows=0 loops=1)
-> Covering index lookup on SidebarCategories using idx_sidebarcategories_userid_teamid (UserId='', TeamId='') (cost=0.592 rows=3) (actual time=0.0105..0.0134 rows=3 loops=1)
-> Covering index lookup on SidebarChannels using idx_sidebarchannels_categoryid (CategoryId=sidebarcategories.Id) (cost=1.39 rows=4.46) (actual time=0.00999..0.00999 rows=0 loops=3)
```
Performance improvement from 512ms to 0.12ms.
https://mattermost.atlassian.net/browse/MM-64209
```release-note
NONE
```
* Make the Mobile Security settings available on Enterprise Advance
* rename to minLicenseTier
* used license tier checks in system console
* lint fix
* renamed license in test
* Made license name display in single line
---------
Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
* Prevents the API from updating synced CPA values
The patch functions for CPA values now accept a parameter that checks
if they should allow for synced values to be updated, and prevent
those updates if necessary
* Fix linter
* Fix parameter after merge
---------
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Scott Bishel <scott.bishel@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>