You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 2dd604a
Browse filesBrowse the repository at this point in the historyBrowse files
perf(users): check roles on request or on a schedule, not on every admin load (#49)
* perf(users): check roles on request or on a schedule, not on every admin load
The users screen, its Out of sync view and the WorkOS Users settings tab each called RoleMapper::get_out_of_sync_users(), which loaded every member of the organization one get_user_by() at a time. On a site with 25,000 members that is ~50,000 queries and 17 s per load with an empty object cache, and 2.8 s with a warm one.
RoleSyncCheck reads members in batches (one JOIN over memberships, users and capabilities per 1,000 members) and stores the result. It runs when an admin clicks Check now on WorkOS -> Users, or on an hourly/daily schedule when Action Scheduler is loaded. Between runs the stored result follows role and membership changes one user at a time. The admin screens read the stored result and never compute it.
The users list also loads the page's memberships in one query (Manager::prime_user_orgs) instead of one per row for the role mismatch badge.
Also: use imports instead of fully qualified class names in the touched files.
* chore(uninstall): remove the role sync check option and scheduled actions
|`src/WorkOS/Sync/UserSync.php`| User sync (inbound/outbound) |
167
167
|`src/WorkOS/Sync/RoleMapper.php`| WorkOS role → WP role mapping |
168
+
|`src/WorkOS/Sync/RoleSyncCheck.php`| Which members' WP role doesn't match the role map. Batched (one JOIN query per 1,000 members), run by "Check now" on WorkOS → Users or on an Action Scheduler schedule (`role_sync_schedule`: off/hourly/daily, only offered when AS is loaded). Stores the result in `workos_role_sync_check` (not autoloaded, stale when env/org/role map change) and rechecks single users on role and `workos_org_membership_changed`. Admin screens read `result()`; nothing is computed on page load. |
@@ -1859,14 +1848,159 @@ public function render_role_map(): void {
1859
1848
echo'<p class="description" style="margin-top:8px">' . esc_html__( 'The "member" role is used as the default fallback.', 'integration-workos' ) . '</p>';
1860
1849
}
1861
1850
1851
+
/**
1852
+
* Last role sync check: what it found and when, a "Check now" button, and the schedule
1853
+
* when Action Scheduler is available. Shows the stored result; nothing is computed here.
1854
+
*/
1855
+
privatefunctionrender_role_sync_status(): void {
1856
+
if ( ! workos()->is_enabled() || empty( Config::get_organization_id() ) ) {
1857
+
return;
1858
+
}
1859
+
1860
+
$result = RoleSyncCheck::result();
1861
+
$running = RoleSyncCheck::is_running();
1862
+
1863
+
if ( $running ) {
1864
+
$message = __( 'Role sync check is running in the background. Reload to see the result.', 'integration-workos' );
1865
+
$class = 'notice-info';
1866
+
} elseif ( ! $result ) {
1867
+
$message = __( 'Roles haven\'t been checked against this role map yet.', 'integration-workos' );
1868
+
$class = 'notice-info';
1869
+
} elseif ( $result['count'] > 0 ) {
1870
+
$message = sprintf(
1871
+
/* translators: 1: number of out-of-sync users, 2: number of members checked, 3: time since the check */
1872
+
_n(
1873
+
'%1$s of %2$s members has a WordPress role that doesn\'t match their WorkOS role mapping. Checked %3$s ago.',
1874
+
'%1$s of %2$s members have a WordPress role that doesn\'t match their WorkOS role mapping. Checked %3$s ago.',
1875
+
$result['count'],
1876
+
'integration-workos'
1877
+
),
1878
+
number_format_i18n( $result['count'] ),
1879
+
number_format_i18n( $result['members'] ),
1880
+
human_time_diff( $result['checked_at'] )
1881
+
);
1882
+
$class = 'notice-warning';
1883
+
} else {
1884
+
$message = sprintf(
1885
+
/* translators: 1: number of members checked, 2: time since the check */
1886
+
__( 'All %1$s members match the role mapping. Checked %2$s ago.', 'integration-workos' ),
add_settings_error( 'workos_messages', 'workos_role_check', __( 'Role sync check started in the background.', 'integration-workos' ), 'info' );
1965
+
} elseif ( 'done' === $outcome && $result ) {
1966
+
add_settings_error(
1967
+
'workos_messages',
1968
+
'workos_role_check',
1969
+
sprintf(
1970
+
/* translators: 1: members checked, 2: out-of-sync users */
1971
+
__( 'Role sync check finished: %1$s members checked, %2$s out of sync.', 'integration-workos' ),
1972
+
number_format_i18n( $result['members'] ),
1973
+
number_format_i18n( $result['count'] )
1974
+
),
1975
+
$result['count'] > 0 ? 'warning' : 'success'
1976
+
);
1977
+
} else {
1978
+
add_settings_error( 'workos_messages', 'workos_role_check', __( 'No organization is configured, so there is nothing to check.', 'integration-workos' ), 'error' );
0 commit comments