* Admin/APC(u): fix error in clear cache: if APC(u) runs out of memory clearing just instance cache clear whole cache

This commit is contained in:
Ralf Becker 2016-07-28 12:02:01 +02:00
parent cc7d9cbba4
commit 96caf6effd
6 changed files with 61 additions and 24 deletions

View File

@ -114,8 +114,7 @@ class admin_hooks
$file['Clear cache and register hooks'] = array(
'id' => 'admin/clear_cache',
'no_lang' => true,
'link' => "javascript:egw.message('".lang('Clear cache and register hooks') . "<br />" .lang('Please wait...')."','info'); " .
"egw.json('admin.admin_hooks.ajax_clear_cache').sendRequest(true);"
'link' => "javascript:app.admin.clear_cache();",
);
}
@ -164,7 +163,7 @@ class admin_hooks
{
$GLOBALS['egw']->redirect_link('/index.php');
}
Api\Cache::flush(Api\Cache::INSTANCE);
Api\Cache::flush(Api\Cache::INSTANCE, !empty($_GET['errored']) ? "all" : null);
Api\Image::invalidate();

View File

@ -1142,5 +1142,21 @@ app.classes.admin = AppJS.extend(
{
this.egw.open_link(_action.data.url, _action.data.target || '_blank', _action.data.popup);
}
},
/**
* Clear instance cache
*
* If there is an error on server-side, resend request with an parameter allowing
* cache to use different method not requiring eg. so much memory
*/
clear_cache: function()
{
this.egw.message(this.egw.lang('Clear cache and register hooks')+"\n"+this.egw.lang('Please wait...'),'info');
this.egw.json('admin.admin_hooks.ajax_clear_cache').sendRequest(true, undefined, jQuery.proxy(function(_xmlhttp, _err)
{
this.egw.json('admin.admin_hooks.ajax_clear_cache&errored=1').sendRequest(true);
}, this));
}
});

View File

@ -97,10 +97,12 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
* Sends the assembled request to the server
* @param {boolean} [async=false] Overrides async provided in constructor to give an easy way to make simple async requests
* @param {string} method ='POST' allow to eg. use a (cachable) 'GET' request instead of POST
* @param {function} error option error callback(_xmlhttp, _err) used instead our default this.error
*
* @return {jqXHR} jQuery jqXHR request object
*/
json_request.prototype.sendRequest = function(async,method) {
json_request.prototype.sendRequest = function(async, method, error)
{
if(typeof async != "undefined")
{
this.async = async;
@ -126,23 +128,31 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
dataType: 'json',
type: method || 'POST',
success: this.handleResponse,
error: function(_xmlhttp, _err) {
// Don't error about an abort
if(_err !== 'abort')
{
this.egw.message.call(this.egw, this.egw.lang('A request to the EGroupware server returned with an error')+': '+_xmlhttp.statusText+' ('+_xmlhttp.status+
")\n\n"+this.egw.lang('Please reload the EGroupware desktop (F5 / Cmd+r).')+"\n"+
this.egw.lang('If the error persists, contact your administrator for help and ask to check the error-log of the webserver.')+
"\n\nURL: "+this.url+"\n"+(_xmlhttp.getAllResponseHeaders() ? _xmlhttp.getAllResponseHeaders().match(/^Date:.*$/m)[0]:''));
this.egw.debug('error', 'Ajax request to', this.url, ' failed: ', _err, _xmlhttp.status, _xmlhttp.statusText);
}
}
error: error || this.handleError
});
return this.request;
};
/**
* Default error callback displaying error via egw.message
*
* @param {XMLHTTP} _xmlhttp
* @param {string} _err
*/
json_request.prototype.handleError = function(_xmlhttp, _err) {
// Don't error about an abort
if(_err !== 'abort')
{
this.egw.message.call(this.egw, this.egw.lang('A request to the EGroupware server returned with an error')+': '+_xmlhttp.statusText+' ('+_xmlhttp.status+
")\n\n"+this.egw.lang('Please reload the EGroupware desktop (F5 / Cmd+r).')+"\n"+
this.egw.lang('If the error persists, contact your administrator for help and ask to check the error-log of the webserver.')+
"\n\nURL: "+this.url+"\n"+(_xmlhttp.getAllResponseHeaders() ? _xmlhttp.getAllResponseHeaders().match(/^Date:.*$/m)[0]:''));
this.egw.debug('error', 'Ajax request to', this.url, ' failed: ', _err, _xmlhttp.status, _xmlhttp.statusText);
}
};
json_request.prototype.handleResponse = function(data) {
if (data && typeof data.response != 'undefined')
{

View File

@ -617,7 +617,7 @@ class Cache
* Flush (delete) whole (instance) cache or application/class specific part of it
*
* @param string $level =self::INSTANCE
* @param string $app =null
* @param string $app =null app-name or "all" to empty complete cache
*/
static public function flush($level=self::INSTANCE, $app=null)
{
@ -628,7 +628,7 @@ class Cache
}
else
{
if (!$provider->flush(self::keys($level, $app)))
if (!$provider->flush($app !== "all" ? self::keys($level, $app) : array()))
{
if ($level == self::INSTANCE)
{

View File

@ -144,15 +144,18 @@ class Apc extends Base implements Provider
/**
* Delete all data under given keys
*
* If no keys are given whole APC cache is cleared, which should allways
* work and can not run out of memory as the iterator sometimes does.
*
* @param array $keys eg. array($level,$app,$location)
* @return boolean true on success, false on error (eg. $key not set)
* @return boolean true on success, false on error (eg. on iterator available)
*/
function flush(array $keys)
{
// APC >= 3.1.1, but also seems to be missing if apc is disabled eg. for cli
if (!class_exists('APCIterator'))
if (!class_exists('APCIterator') || !$keys)
{
if (function_exists('apc_clear_cache')) apc_clear_cache ('user');
if (function_exists('apc_clear_cache')) apc_clear_cache('user');
return false;
}

View File

@ -143,11 +143,20 @@ class Apcu extends Base implements Provider
/**
* Delete all data under given keys
*
* @param array $keys eg. array($level,$app,$location)
* @return boolean true on success, false on error (eg. $key not set)
* If no keys are given whole APCu cache is cleared, which should allways
* work and can not run out of memory as the iterator sometimes does.
*
* @param array $keys eg. array($level,$app,$location) or array() to clear whole cache
* @return boolean true on success, false on error (eg. on iterator available)
*/
function flush(array $keys)
{
if (!$keys && function_exists('apcu_clear_cache'))
{
apcu_clear_cache();
return true;
}
// APCu > 5 has APCUIterator
if (class_exists('APCUIterator'))
{
@ -160,7 +169,7 @@ class Apcu extends Base implements Provider
}
else
{
if (function_exists('apcu_clear_cache')) apcu_clear_cache ();
if (function_exists('apcu_clear_cache')) apcu_clear_cache();
return false;
}