Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/wp-admin/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@
wp_schedule_event( time(), 'daily', 'delete_expired_transients' );
}

// Schedule collaboration data cleanup.
if ( wp_is_collaboration_enabled()
&& ! wp_next_scheduled( 'wp_delete_old_collaboration_data' )
&& ! wp_installing()
) {
wp_schedule_event( time(), 'daily', 'wp_delete_old_collaboration_data' );
}

set_screen_options();

$date_format = __( 'F j, Y' );
Expand Down
35 changes: 35 additions & 0 deletions src/wp-admin/includes/schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,41 @@ function wp_get_db_schema( $scope = 'all', $blog_id = null ) {
KEY post_parent (post_parent),
KEY post_author (post_author),
KEY type_status_author (post_type,post_status,post_author)
) $charset_collate;
/*
* Collaboration and awareness use separate tables because they have
* opposite uniqueness requirements on the same columns.
*
* Collaboration rows are append-only: a single client writes many rows
* per room over time, so no UNIQUE constraint is possible on (room, client_id).
*
* Awareness rows require exactly one per client per room. The UNIQUE KEY
* on (room, client_id) enables INSERT ... ON DUPLICATE KEY UPDATE for
* atomic upsert, preventing the duplicate-row race condition that occurs
* with DELETE+INSERT under concurrent requests.
*/
CREATE TABLE $wpdb->collaboration (
id bigint(20) unsigned NOT NULL auto_increment,
room varchar($max_index_length) NOT NULL default '',
type varchar(32) NOT NULL default '',
client_id varchar(32) NOT NULL default '',
update_value longtext NOT NULL,
created_at datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id),
KEY room (room,id),
KEY created_at (created_at)
) $charset_collate;
CREATE TABLE $wpdb->awareness (
id bigint(20) unsigned NOT NULL auto_increment,
room varchar($max_index_length) NOT NULL default '',
client_id varchar(32) NOT NULL default '',
wp_user_id bigint(20) unsigned NOT NULL default '0',
update_value longtext NOT NULL,
created_at datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id),
UNIQUE KEY room_client (room,client_id),
KEY room_created_at (room,created_at),
KEY created_at (created_at)
) $charset_collate;\n";

// Single site users table. The multisite flavor of the users table is handled below.
Expand Down
2 changes: 1 addition & 1 deletion src/wp-admin/includes/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ function upgrade_all() {
upgrade_682();
}

if ( $wp_current_db_version < 61644 ) {
if ( $wp_current_db_version < 61699 ) {
upgrade_700();
}

Expand Down
20 changes: 20 additions & 0 deletions src/wp-includes/class-wpdb.php
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ class wpdb {
'term_relationships',
'termmeta',
'commentmeta',
'collaboration',
'awareness',
);

/**
Expand Down Expand Up @@ -404,6 +406,24 @@ class wpdb {
*/
public $posts;

/**
* WordPress Collaboration table.
*
* @since 7.0.0
*
* @var string
*/
public $collaboration;

/**
* WordPress Awareness table.
*
* @since 7.0.0
*
* @var string
*/
public $awareness;

/**
* WordPress Terms table.
*
Expand Down
50 changes: 49 additions & 1 deletion src/wp-includes/collaboration.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@
* @since 7.0.0
*/

/**
* Checks whether real-time collaboration is enabled.
*
* The feature requires both the site option and the database schema
* introduced in db_version 61699.
*
* @since 7.0.0
*
* @return bool True if collaboration is enabled, false otherwise.
*/
function wp_is_collaboration_enabled() {
return get_option( 'wp_enable_real_time_collaboration' )
&& get_option( 'db_version' ) >= 61699;
}

/**
* Injects the real-time collaboration setting into a global variable.
*
Expand All @@ -18,7 +33,7 @@
function wp_collaboration_inject_setting() {
global $pagenow;

if ( ! get_option( 'wp_enable_real_time_collaboration' ) ) {
if ( ! wp_is_collaboration_enabled() ) {
return;
}

Expand All @@ -34,3 +49,36 @@ function wp_collaboration_inject_setting() {
'after'
);
}

/**
* Deletes stale collaboration data from the collaboration table.
*
* Removes collaboration rows older than 7 days and awareness rows older than
* 60 seconds. Rows left behind by abandoned collaborative editing sessions
* are cleaned up to prevent unbounded table growth.
*
* @since 7.0.0
*/
function wp_delete_old_collaboration_data() {
if ( ! wp_is_collaboration_enabled() ) {
return;
}

global $wpdb;

// Clean up collaboration rows older than 7 days.
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$wpdb->collaboration} WHERE created_at < %s",
gmdate( 'Y-m-d H:i:s', time() - WEEK_IN_SECONDS )
)
);

// Clean up awareness rows older than 60 seconds (2× the 30-second awareness timeout as a buffer).
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$wpdb->awareness} WHERE created_at < %s",
gmdate( 'Y-m-d H:i:s', time() - 60 )
)
);
}
Loading
Loading