Last active
February 11, 2021 10:01
-
-
Save chwnam/c441ca20952856ca0e1a9cd0d657fac9 to your computer and use it in GitHub Desktop.
Race Cond - 옵션 업데이트가 매우 빈번히 일어날 때 주의할 사항
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: Race Cond | |
* Plugin URI: https://gist.github.com/chwnam/c441ca20952856ca0e1a9cd0d657fac9 | |
* | |
* @link https://blog.changwoo.pe.kr/option-race-condition/ | |
*/ | |
add_action( 'admin_menu', 'rcond_admin_menu' ); | |
function rcond_admin_menu() { | |
add_menu_page( 'RCond', 'RCond', 'administrator', 'rcond', 'rcond_output_menu' ); | |
} | |
function rcond_output_menu() { | |
$autoload_yes = get_option( 'rcond_autoload_yes', [] ); | |
$autoload_no = get_option( 'rcond_autoload_no', [] ); | |
?> | |
<div class="wrap"> | |
<h2>Autoload Yes</h2> | |
<a href="#" id="autoload-yes-all">모두 동시 클릭</a> | |
<ul> | |
<?php for ( $i = 1; $i <= 50; ++ $i ) : ?> | |
<li> | |
<a href="#" | |
class="autoload-yes" | |
data-id="<?php echo intval( $i ); ?>"> | |
ID #<?php echo intval( $i ); ?> 클릭해 실햄</a> | |
<?php if ( isset( $autoload_yes[ $i ] ) ) : ?> | |
<span>clicked</span> | |
<?php endif; ?> | |
</li> | |
<?php endfor; ?> | |
</ul> | |
</div> | |
<div class="wrap"> | |
<h2>Autoload No</h2> | |
<a href="#" id="autoload-no-all">모두 동시 클릭</a> | |
<ul> | |
<?php for ( $i = 1; $i <= 50; ++ $i ) : ?> | |
<li> | |
<a href="#" | |
class="autoload-no" | |
data-id="<?php echo intval( $i ); ?>"> | |
ID #<?php echo intval( $i ); ?> 클릭해 실햄</a> | |
<?php if ( isset( $autoload_no[ $i ] ) ) : ?> | |
<span>clicked</span> | |
<?php endif; ?> | |
</li> | |
<?php endfor; ?> | |
</ul> | |
</div> | |
<hr> | |
<p> | |
<button id="reset" type="button" class="button">재설정하기</button> | |
</p> | |
<script> | |
(function ($) { | |
$('.autoload-yes').on('click', function (e) { | |
var $this = $(this); | |
e.preventDefault(); | |
$.ajax('/wp-admin/admin-ajax.php', { | |
data: { | |
action: 'rcond_autoload_yes', | |
id: $this.data('id') | |
}, | |
success: function () { | |
$this.after(' <span>clicked</span>'); | |
} | |
}); | |
}); | |
$('.autoload-no').on('click', function (e) { | |
var $this = $(this); | |
e.preventDefault(); | |
$.ajax('/wp-admin/admin-ajax.php', { | |
data: { | |
action: 'rcond_autoload_no', | |
id: $this.data('id') | |
}, | |
success: function () { | |
$this.after(' <span>clicked</span>'); | |
} | |
}); | |
}); | |
$('#reset').on('click', function () { | |
$.ajax('/wp-admin/admin-ajax.php', { | |
data: { | |
action: 'rcond_reset' | |
}, | |
success() { | |
window.location.reload(); | |
} | |
}); | |
}); | |
$('#autoload-yes-all').on('click', function (e) { | |
e.preventDefault(); | |
$('.autoload-yes').each(function (idx, elem) { | |
$(elem).trigger('click'); | |
}); | |
}); | |
$('#autoload-no-all').on('click', function (e) { | |
e.preventDefault(); | |
$('.autoload-no').each(function (idx, elem) { | |
$(elem).trigger('click'); | |
}); | |
}); | |
})(jQuery); | |
</script> | |
<?php | |
} | |
add_action( 'wp_ajax_rcond_autoload_yes', 'rcond_autoload_yes' ); | |
function rcond_autoload_yes() { | |
global $wpdb; | |
$id = intval( $_GET['id'] ?? '0' ); | |
$value = get_option( 'rcond_autoload_yes', [] ); | |
if ( ! is_array( $value ) ) { | |
$value = []; | |
} | |
$value[ $id ] = true; | |
update_option( 'rcond_autoload_yes', $value ); | |
wp_send_json_success(); | |
} | |
add_action( 'wp_ajax_rcond_autoload_no', 'rcond_autoload_no' ); | |
function rcond_autoload_no() { | |
// DB Locking | |
// global $wpdb; | |
// | |
// $filter_added = false; | |
// add_filter( 'pre_option_rcond_autoload_no', function ( $value ) use ( &$filter_added ) { | |
// if ( ! $filter_added ) { | |
// add_filter( 'query', 'rcond_query_for_update' ); | |
// $filter_added = true; | |
// } | |
// return $value; | |
// } ); | |
// | |
// wp_suspend_cache_addition( false ); | |
// $wpdb->query( 'SET AUTOCOMMIT = 0;' ); | |
// $wpdb->query( 'START TRANSACTION' ); | |
// Semaphore | |
// $sem = sem_get( 9090 ); | |
// sem_acquire( $sem ); | |
$id = intval( $_GET['id'] ?? '0' ); | |
$value = get_option( 'rcond_autoload_no', [] ); | |
if ( ! is_array( $value ) ) { | |
$value = []; | |
} | |
$value[ $id ] = true; | |
update_option( 'rcond_autoload_no', $value, false ); | |
// Semaphore | |
// sem_release( $sem ); | |
// if ( 50 === count( $value ) ) { | |
// sem_remove( $sem ); | |
// } | |
// DB Locking | |
// $wpdb->query( 'COMMIT' ); | |
wp_send_json_success(); | |
} | |
function rcond_query_for_update( $query ) { | |
remove_filter( 'query', 'rcond_query_for_update' ); | |
$query .= ' FOR UPDATE'; | |
return $query; | |
} | |
add_action( 'wp_ajax_rcond_reset', 'rcond_reset' ); | |
function rcond_reset() { | |
update_option( 'rcond_autoload_yes', [], true ); | |
update_option( 'rcond_autoload_no', [], false ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment