Come together with the global Drupal community in Rotterdam, 28 Sept – 1 Oct 2026. Sessions, contribution, connection, and Early Bird savings until 8 June.
its missing code to cache messages as they are read, and to put a user object in APC with a list of the chat's they have access to, but they would both be pretty simple. on a windoze machine, so no patch yet...
/**
* Whether or not we have APC functionality.
*/
define('CHATROOM_APC_ENABLED', function_exists('apc_fetch'));
/**
* @file
* Process chatroom polling requests.
*
* This file is a performance hack, aimed at making moderately sized rooms
* possible with this module.
*
* The intent is to handle the polling requests from chatrooms without doing
* a full Drupal bootstrap unless absolutely necessary. All simple polling
* requests are handled by this script, as they are by far the most common
* type of request, and are very easy to check against a cache.
*
* First, we check to see if the last message seen in a given chat client-side
* is older than the latest message in that chat server-side.
*
* Only if the chat being polled has messages newer than what the requesting
* client has seen do we bootstrap Drupal.
*/
// We need the $latest_msg_id, $chat_id and $chat_cache_file to check the
// cache for this chat.
if (!isset($_POST['latest_msg_id']) || !preg_match('/^\d+$/', $_POST['latest_msg_id'])) {
exit;
}
$client_latest_msg_id = $_POST['latest_msg_id'];
$server_latest_message_id = FALSE;
if (!isset($_POST['chat_id']) || !preg_match('/^\d+$/', $_POST['chat_id'])) {
exit;
}
$chat_id = $_POST['chat_id'];
if (!isset($_POST['chat_cache_directory']) || !is_dir($_POST['chat_cache_directory'])) {
exit;
}
$chat_cache_file = $_POST['chat_cache_directory'] . '/chatroom.chat.' . $chat_id . '.cache';
if (!isset($_POST['skip_cache'])) {
exit;
}
$skip_cache = $_POST['skip_cache'] == 1 ? TRUE : FALSE;
// We let the client signal that we should skip the cache. Right now we're
// using this to make sure users last-seen time is updated, and there may
// be more uses for it down the track.
if (!$skip_cache && file_exists($chat_cache_file)) {
// Do a quick DoS check - we don't validate the path, so we have to make
// sure we're not reading arbitrarily big files into memory. Our cache file
// should contain a single numeric id. So, if the file is bigger than 25
// bytes, something is fishy, and we should just bail out.
$file_stats = stat($chat_cache_file);
if ($file_stats['size'] > 25) {
exit;
}
$server_latest_msg_id = trim(file_get_contents($chat_cache_file));
if ($server_latest_msg_id == $client_latest_msg_id) {
print json_encode(array('data' => array('cacheHit' => 1, 'messages' => array())));
exit;
}
}
if ($chat_user = chatroom_get_cached_user()) {
if (in_array($chat_id, $chat_user->allowed_chats)) {
// Try to get messages from our cache.
if ($cached_messages = chatroom_get_cached_messages($chat_id, $client_latest_message_id)) {
print json_encode(array('data' => array('cacheHit' => 1, 'messages' => $cached_messages)));
exit;
}
}
}
/**
* Get a cached user object to check access for the given chat.
*/
function chatroom_get_cached_user() {
if (!CHATROOM_APC_ENABLED) {
return FALSE;
}
require_once './includes/bootstrap.php';
drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
return apc_fetch('chatroom_user_cache_' . $_COOKIE[session_name()]);
}
/**
* Get cached messages for the given chat newer than $client_latest_message_id.
*/
function chatroom_get_cached_messages($chat_id, $client_latest_message_id) {
if (!CHATROOM_APC_ENABLED) {
return FALSE;
}
$valid_cached_messages = array();
if ($cached_messages = apc_fetch('chatroom_message_cache_' . $chat_id)) {
foreach ($cached_messages as $message) {
if ($message->id > $client_latest_message_id) {
$valid_cached_messages[] = $message;
}
}
}
return $valid_cached_messages;
}
// Make this look like a normal request to Drupal, then execute index.php.
$_GET['q'] = "chatroom/chat/get/latest/messages/$chat_id/$client_latest_msg_id";
require_once './index.php';
@justinrandell: I have tested the dev version with apc cache support. It runs incredibly smooth and even more, now the php threads per chat copy aren't generated. It seens php is no more called to solve chat refresh. I have tried the same experiment as I did. I have opened 10 browser tabs all with the same chat and I have written a text in one of them. I have been checking ps to see if php was beeing called like before and no. I hope more people test it so possible bugs are detected, but this dev version should see stable state as soon as possible.
justinrandell - note that your 2.x-dev changes are not jet applied to 3.x-dev branch. This branch wasn't updated for a while (while i was confused you've committed this to 2.x - although you state 3.x was the feature branch regarding project page.)
Justinrandell
I understand your implementation of the apc interface. However i wonder why we're not relying on drupal core cache_get and cache_set methods that are being bound to e.g. apc if you use some cache replacement like cacherouter.
This approach would allow us to support any caching mechanism that is supported by drupal and its extensions without chatroom specific code.
This might look like some further overhead as long as you don't enable any specific custom speedup cache like apc, memcached, .... Note it also supports filebased cache.
OK, performance is the answer. Chatroom now has its own pluggable cache to be speedy. According to justinrandell it would need to bootstrap to a higher heavyer level to get drupal cache functions work.
Comments
Comment #1
Anonymous (not verified) commentedhow about this totally untested code idea?
its missing code to cache messages as they are read, and to put a user object in APC with a list of the chat's they have access to, but they would both be pretty simple. on a windoze machine, so no patch yet...
Comment #2
Anonymous (not verified) commentedComment #3
Anonymous (not verified) commentedworking on this, patch coming soon. *much* faster now.
Comment #4
Anonymous (not verified) commentedi've committed early support for this:
http://drupal.org/cvs?commit=341232
much faster, please test.
Comment #5
miro_dietikerSounds cool, man! Going to test this ASAP in deep detail.
Comment #6
Farreres commented@justinrandell: I have tested the dev version with apc cache support. It runs incredibly smooth and even more, now the php threads per chat copy aren't generated. It seens php is no more called to solve chat refresh. I have tried the same experiment as I did. I have opened 10 browser tabs all with the same chat and I have written a text in one of them. I have been checking ps to see if php was beeing called like before and no. I hope more people test it so possible bugs are detected, but this dev version should see stable state as soon as possible.
Comment #7
Anonymous (not verified) commentedclosing, as i've released 6.x-2.8 with this feature included.
Comment #8
miro_dietikerjustinrandell - note that your 2.x-dev changes are not jet applied to 3.x-dev branch. This branch wasn't updated for a while (while i was confused you've committed this to 2.x - although you state 3.x was the feature branch regarding project page.)
Comment #9
Anonymous (not verified) commented@miro_dietiker yep, sorry for the confusion. are you using the dev branch? have you tried the new cache setup?
Comment #10
miro_dietikerjustinrandell - we're using a DRUPAL-6--2 checkout in production.
Any issues - if any - will/would be reported very soon. ;-)
Comment #11
miro_dietikerJustinrandell
I understand your implementation of the apc interface. However i wonder why we're not relying on drupal core cache_get and cache_set methods that are being bound to e.g. apc if you use some cache replacement like cacherouter.
This approach would allow us to support any caching mechanism that is supported by drupal and its extensions without chatroom specific code.
This might look like some further overhead as long as you don't enable any specific custom speedup cache like apc, memcached, .... Note it also supports filebased cache.
Comment #12
miro_dietikerOK, performance is the answer. Chatroom now has its own pluggable cache to be speedy. According to justinrandell it would need to bootstrap to a higher heavyer level to get drupal cache functions work.