/[drupal]/contributions/modules/ad_memcache/ad_cache_memcache.inc
ViewVC logotype

Contents of /contributions/modules/ad_memcache/ad_cache_memcache.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Sat Apr 18 03:04:23 2009 UTC (7 months, 1 week ago) by jeremy
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--2
File MIME type: text/x-php
Branched 6.x from 5.x-1.7, removed from core ad module (too many people were
blindly enabling this module and then running into problems if they didn't
have memcached installed).
1 <?php
2 // $Id: ad_memcache.inc,v 1.1.2.6.2.6 2009/02/16 23:12:28 jeremy Exp $
3
4 /**
5 * @file
6 * Memcache include.
7 *
8 * Copyright (c) 2005-2009.
9 * Jeremy Andrews <jeremy@tag1consulting.com>.
10 */
11
12 /**
13 * Initialization function.
14 */
15 function ad_cache_memcache_open() {
16 _debug_echo('Ad memcache: open');
17 return ad_memcache_init();
18 }
19
20 /**
21 * Return hook definition.
22 */
23 function ad_cache_memcache_hook($hook) {
24 static $cache = NULL;
25 _debug_echo("Ad memcache: hook($hook)");
26
27 if (empty($cache)) {
28 _debug_echo('Ad memcache: retrieving hook info from cache.');
29 $cache = ad_memcache_get('ad-cache-hooks');
30 }
31 if (isset($cache["hook_$hook"]) && is_array($cache["hook_$hook"])) {
32 return $cache["hook_$hook"];
33 }
34 else {
35 _debug_echo("File cache: hook '$hook' not found.");
36 }
37 return array();
38 }
39
40 /**
41 * Return hook definition.
42 */
43 function ad_cache_memcache_get_cache($data = NULL) {
44 static $cache = NULL;
45
46 if (!isset($cache)) {
47 $cache = ad_memcache_get('ad-cache-hooks');
48 if (isset($cache['external-hooks'])) {
49 $cache = $cache['external-hooks'];
50 }
51 else {
52 $cache = array();
53 }
54 }
55
56 if (isset($cache[$data])) {
57 return $cache[$data];
58 }
59 else {
60 return array();
61 }
62 }
63
64 function ad_cache_memcache_id($type, $id, $hostid) {
65 _debug_echo("Ad memcache: get id type($type) id($id) hostid($hostid)");
66 switch ($type) {
67 case 'host':
68 // TODO:
69 break;
70
71 case 'nids':
72 return explode(',', $id);
73
74 case 'tids':
75 $ids = ad_memcache_get("ad-taxonomy-cache-$id");
76 if (!$ids || empty($ids)) {
77 $taxonomy = ad_memcache_get('ad-taxonomy');
78 $cache = array();
79 $ids = explode(',', $id);
80 foreach ($ids as $tid) {
81 if (is_array($taxonomy[$tid])) {
82 $cache += $taxonomy[$tid];
83 }
84 }
85 // Rebuild keys from 0, cache for quick re-use on next ad display.
86 $ids = array_values($cache);
87 ad_memcache_set("ad-taxonomy-cache-$id", $ids);
88 }
89 return $ids;
90
91 case 'default':
92 $taxonomy = ad_memcache_get('ad-taxonomy');
93 return $taxonomy[0];
94
95 default:
96 _debug_echo("Ad memcache: unknown id tpye '$type'.");
97 break;
98 }
99 }
100
101 /**
102 * Filter out advertisements that don't exist, or have already been displayed.
103 */
104 function ad_cache_memcache_validate($ads, $displayed, $hostid) {
105 $valid = array();
106 if (is_array($ads)) {
107 $valid_ads = ad_memcache_get('ad-ads');
108 foreach ($ads as $aid) {
109 // Only include aids that are in our cache, others are not valid in our
110 // context. Also, don't display the same ad twice.
111 if (isset($valid_ads[$aid]) && !in_array($aid, $displayed)) {
112 $valid[] = $aid;
113 }
114 }
115 }
116 if (adserve_variable('debug')) {
117 $count = sizeof($valid);
118 _debug_echo("Ad memcache: found $count valid advertisements.");
119 }
120 return $valid;
121 }
122
123 /**
124 * Display the actual advertisement.
125 */
126 function ad_cache_memcache_display_ad($aid) {
127 // TODO: Validate hostid.
128 $hostid = adserve_variable('hostid') ? adserve_variable('hostid') : 'none';
129 /*
130 if ($hostid != 'none' && !isset($cache['hostid'][$hostid])) {
131 _debug_echo("File cache: invalid hostid: '$hostid'.");
132 $output = 'You do not have permission to display ads.';
133 }
134 else {
135 */
136 $ad = ad_memcache_get_ad($aid);
137 return $ad->display;
138 }
139
140 function ad_memcache_get_ad($aid) {
141 static $load = FALSE;
142
143 $ad = ad_memcache_get("ad-aid-$aid");
144
145 if (!$load && !is_object($ad)) {
146 $load = TRUE;
147 adserve_bootstrap();
148 $ad_memcache_build = variable_get('ad_memcache_build', '');
149 if ((time() - $ad_memcache_build) >= 60) {
150 ad_memcache_build();
151 $ad = ad_memcache_get("ad-aid-$aid");
152 }
153 }
154
155 return $ad;
156 }
157
158 /**
159 * Increment impressions counter in memcache.
160 */
161 function ad_cache_memcache_increment($action, $aid) {
162 static $timestamp = NULL;
163
164 if (!isset($timestamp)) {
165 $timestamp = date('YmdH');
166 }
167 $group = adserve_variable('group');
168 $hostid = adserve_variable('hostid') ? adserve_variable('hostid') : 'none';
169
170 $extra = adserve_invoke_hook('increment_extra', 'merge', $action, $aid);
171 if (is_array($extra) && !empty($extra)) {
172 $extra = implode('|,|', $extra);
173 }
174 else if (empty($extra)) {
175 $extra = '';
176 }
177 adserve_variable('extra', $extra);
178
179 _debug_echo("Memcache: increment action($action) aid($aid) group($group) hostid($hostid) extra($extra).");
180
181 $counters = ad_memcache_get("ad-counters-$aid");
182 $update = TRUE;
183 if (!is_array($counters) || !isset($counters["$action:$group:$hostid:$extra:$timestamp"])) {
184 _debug_echo("Memcache: adding map: action($action) aid($aid) group($group) hostid($hostid) extra($extra) timestamp($timestamp)");
185 ad_memcache_increment_map($action, $aid, $group, $hostid, $extra, $timestamp);
186 }
187
188 $rc = ad_memcache_increment("ad-$action-$aid-$group-$hostid-$extra-$timestamp");
189 _debug_echo("Memcache: incrementing ad-$action-$aid-$group-$hostid-$extra-$timestamp ($rc)");
190 }
191
192 /**
193 * The maximum time any process can hold a given lock, in seconds.
194 */
195 define('AD_MEMCACHE_LOCK_LIMIT', 2);
196
197 /**
198 * Store a value in memcache.
199 */
200 function ad_memcache_set($key, $value, $timeout = 86400) {
201 $memcache = ad_memcache_init();
202
203 return $memcache->set($key, $value, MEMCACHE_COMPRESSED, $timeout);
204 }
205
206 /**
207 * Store a value in memcache.
208 */
209 function ad_memcache_add($key, $value, $timeout = 86400) {
210 $memcache = ad_memcache_init();
211
212 return $memcache->add($key, $value, MEMCACHE_COMPRESSED, $timeout);
213 }
214
215 /**
216 * Get a value from memcache.
217 */
218 function ad_memcache_get($key) {
219 $memcache = ad_memcache_init();
220
221 return $memcache->get($key);
222 }
223
224 /**
225 * Delete a value from memcache.
226 */
227 function ad_memcache_delete($key) {
228 $memcache = ad_memcache_init();
229
230 return $memcache->delete($key);
231 }
232
233 /**
234 * Get a lock in memcache.
235 */
236 function ad_memcache_lock($key, $wait = TRUE) {
237 $loop = 0;
238 $lock = FALSE;
239 while ($lock == FALSE) {
240 $lock = ad_memcache_add("LOCK-$key-LOCK", TRUE, AD_MEMCACHE_LOCK_LIMIT);
241 if (!$lock && $wait) {
242 if ($loop++ > 50) {
243 // Hard limit of 5 seconds, after which we fail to grab a lock.
244 return FALSE;
245 }
246 // Wait 1/10th of a second and try again.
247 usleep(100000);
248 }
249 else if (!$lock && !$wait) {
250 return FALSE;
251 }
252 }
253 return TRUE;
254 }
255
256 /**
257 * Release a lock in memcache.
258 */
259 function ad_memcache_unlock($key) {
260 ad_memcache_delete("LOCK-$key-LOCK");
261 }
262
263 /**
264 * Increment a numerical value in memcache.
265 */
266 function ad_memcache_increment($key, $value = 1) {
267 $memcache = ad_memcache_init();
268
269 $rc = $memcache->increment($key, $value);
270 if ($rc === FALSE) {
271 // We tried incrementing a counter that hasn't yet been initialized.
272 $rc = $memcache->set($key, $value);
273 if ($rc === FALSE) {
274 // Another process already initialized the counter, increment it.
275 $rc = $memcache->increment($key);
276 }
277 }
278 return $rc;
279 }
280
281 /**
282 * Decrement a numerical value in memcache.
283 */
284 function ad_memcache_decrement($key, $value = 1) {
285 $memcache = ad_memcache_init();
286
287 $rc = $memcache->decrement($key, $value);
288 if ($rc === FALSE) {
289 // We tried incrementing a counter that hasn't yet been initialized.
290 $rc = $memcache->set($key, $value);
291 if ($rc === FALSE) {
292 // Another process already initialized the counter, increment it.
293 $rc = $memcache->decrement($key);
294 }
295 }
296 return $rc;
297 }
298
299 /**
300 * Update mapping which allows us to quickly find stats in memcache when
301 * feeding them into the database.
302 */
303 function ad_memcache_increment_map($action, $aid, $group, $hostid, $extra, $timestamp) {
304 $key = "ad-counters-$aid";
305 if (ad_memcache_lock($key)) {
306 $counters = ad_memcache_get($key);
307 if (!is_array($counters) || empty($counters) || !isset($counters["$action:$group:$hostid:$extra:$timestamp"])) {
308 $counters["$action:$group:$hostid:$extra:$timestamp"] = "$action:$group:$hostid:$extra:$timestamp";
309 ad_memcache_set($key, $counters);
310 }
311 ad_memcache_unlock($key);
312 }
313 }
314
315 /**
316 * Decrement a numerical value in memcache.
317 * TODO: Use the same configuration style as Drupal's memcache module,
318 * supporting multiple memcache servers, etc.
319 */
320 function ad_memcache_init() {
321 static $memcache = NULL;
322
323 if (!$memcache) {
324 _debug_echo("Ad memcache: init, adding server host(localhost) port(11211)");
325 $memcache = new Memcache;
326 $memcache->addServer('localhost', 11211);
327 }
328 return $memcache;
329 }
330
331 /**
332 * Allow external ad selection logic.
333 */
334 function ad_memcache_adserve_select($ads, $invalid) {
335 $cache = array();
336 if ($select_func = ad_memcache_hook($cache, 'include_file_select', 'include_func_select')) {
337 _debug_echo("Memcache: adserve_select: invoking '$select_func()'");
338 if (function_exists($select_func)) {
339 if (is_array($cache) && !empty($cache)) {
340 return $select_func($ads, $invalid, $cache);
341 }
342 else {
343 _debug_echo("Memcache: unexpected error: cache empty.");
344 }
345 }
346 else {
347 _debug_echo("Memcache: adserve_select: '$include_func_select()' not found");
348 }
349 }
350 else {
351 _debug_echo("Memcache: adserve_select: no select function defined");
352 }
353 }
354
355 /**
356 * Allow external exit text.
357 */
358 function ad_memcache_adserve_exit_text() {
359 $cache = array();
360 if ($exit_text_func = ad_memcache_hook($cache, 'include_file_exit_text', 'include_func_exit_text')) {
361 _debug_echo("Memcache: adserve_exit_text: invoking '$exit_text_func()'");
362 if (function_exists($exit_text_func)) {
363 return $exit_text_func();
364 }
365 else {
366 _debug_echo("Memcache: adserve_exit_text: '$exit_text_func()' not found");
367 }
368 }
369 else {
370 _debug_echo("Memcache: adserve_exit_text: no exit_text function defined");
371 }
372 }
373

  ViewVC Help
Powered by ViewVC 1.1.2