1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
<?php
/*
** Copyright (C) 1995-2008 by the ITools Authors.
** This file is part of ITools - the Internet Tools Library
**
** ITools is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**
** ITools is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** it_cache.class - Caching functions
*/
class it_cache
{
static $_fetch_func;
static $_store_func;
static function _defaults($p)
{
$p += array(
'ttl' => 2,
'distributed' => false,
'hostsfile' => '/opt/ultra/etc/memcached.hosts',
);
if (!it::is_live())
$p['distributed'] = false; # Always local cache on non-live systems
return $p;
}
/**
* Get value for specific key from cache. Can be mixed value but no objects. WARNING: only distributed works from shell
* @param $key Key to get value for
* @param $p['distributed'] Use distributed memcache (scalars may become strings) [false]
* @return Value for given key or null
*/
static function get($key, $p = array())
{
$p = it_cache::_defaults($p);
if (isset($GLOBALS['it_cache_local'][$key]))
{
# Use local copy
$result = $GLOBALS['it_cache_local'][$key];
$success = true;
}
else if ($p['distributed'] && ($memcache = it_cache::_get_memcache($p)))
{
$result = @$memcache->get($key);
$success = !$memcache->getResultCode();
}
else
$result = ($func = self::$_fetch_func) ? $func($key, $success) : null;
return $success === false ? null : $result;
}
/**
* Put value for specific key into cache. Can be mixed value but no objects. WARNING: only distributed works from shell
* @param $key Key to put value with
* @param $value Value to put (mixed but no objects allowed)
* @param $p['distributed'] Use distributed memcache (scalars may become strings) [false]
* @param $p['ttl'] Time to live for this key/value-pair in seconds
* @return Returns $value
*/
static function put($key, $value, $p = array())
{
$p = it_cache::_defaults($p);
if ($p['distributed'] && ($memcache = it_cache::_get_memcache($p)))
$success = @$memcache->set($key, $value, $p['ttl']);
else
$success = ($func = self::$_store_func) ? $func($key, $value, $p['ttl']) : null;
if (!$success)
it::error(array('title' => ($p['distributed'] ? "memcache" : self::$_store_func) . " in it_cache::put failed for key '$key'", 'id' => "it_cache_put", 'graceperiod' => 60, 'timewindow' => 10));
$GLOBALS['it_cache_local'][$key] = $value; # Also store local copy
return $value;
}
static function _get_memcache($p)
{
$memcache_id = "it_cache_memcache_" . $p['hostsfile'];
if (!isset($GLOBALS[$memcache_id]) && class_exists("Memcached", false))
{
$memcache = new Memcached;
foreach (array_filter(it::replace(array('[#\s].*' => ""), file($p['hostsfile']))) as $host)
$reachable += intval(@$memcache->addServer($host, 11211));
$GLOBALS[$memcache_id] = $reachable ? $memcache : false;
}
return $GLOBALS[$memcache_id];
}
static function _memcache_local_fetch($key, &$success)
{
if ($memcache = it_cache::_get_memcache(it_cache::_defaults(array())))
{
$result = @$memcache->get(self::_memcache_local_key($key));
$success = !$memcache->getResultCode();
}
return $result;
}
static function _memcache_local_store($key, $value, $ttl)
{
if ($memcache = it_cache::_get_memcache(it_cache::_defaults(array())))
$success = @$memcache->set(self::_memcache_local_key($key), $value, $ttl);
return $success;
}
static function _memcache_local_key($key)
{
return "$key@" . gethostname();
}
}
it_cache::$_fetch_func = function_exists("apcu_fetch") ? "apcu_fetch" : (function_exists("apc_fetch") ? "apc_fetch" : "it_cache::_memcache_local_fetch");
it_cache::$_store_func = function_exists("apcu_store") ? "apcu_store" : (function_exists("apc_store") ? "apc_store" : "it_cache::_memcache_local_store");
|