Issue #2222555 by mikeytown2: Show the delay in the admin screen; add description...
[project/httprl.git] / examples / httprl.examples.php
1 <?php
2 /**
3 * @file
4 * HTTP Parallel Request Library code examples.
5 */
6 ?>
7
8 **Simple HTTP**
9 Request http://drupal.org/.
10
11 <?php
12 // Queue up the request.
13 httprl_request('http://drupal.org/');
14 // Execute request.
15 $request = httprl_send_request();
16
17 // Echo out the results.
18 echo httprl_pr($request);
19 ?>
20
21
22 Request http://drupal.org/robots.txt and save it to tmp folder.
23
24 <?php
25 // Queue up the request.
26 httprl_request('http://drupal.org/robots.txt');
27 // Execute request.
28 $request = httprl_send_request();
29
30 // Save file if we got a 200 back.
31 if ($request['http://drupal.org/robots.txt']->code == 200) {
32 file_put_contents('/tmp/robots.txt', $request['http://drupal.org/robots.txt']->data);
33 }
34 ?>
35
36
37 Request this servers own front page & the node page.
38
39 <?php
40 $options = array(
41 'headers' => array(
42 // Set the Host header to self.
43 'Host' => $_SERVER['HTTP_HOST'],
44 ),
45 );
46 // Build URL to point to front page of this server.
47 $url_front = httprl_build_url_self();
48 // Build URL to point to /node on this server.
49 $url_node = httprl_build_url_self('node');
50 // Queue up the requests.
51 httprl_request($url_front, $options);
52 httprl_request($url_node, $options);
53 // Execute requests.
54 $request = httprl_send_request();
55
56 // Echo out the results.
57 echo httprl_pr($request);
58 ?>
59
60
61 **Non Blocking HTTP Operations**
62
63 Request 10 URLs in a non blocking manner on this server. Checkout watchdog as
64 this should generate 10 404s and the $request object won't contain much info.
65
66 <?php
67 // Set the blocking mode.
68 $options = array(
69 'blocking' => FALSE,
70 'headers' => array(
71 // Set the Host header to self.
72 'Host' => $_SERVER['HTTP_HOST'],
73 ),
74 );
75 // Queue up the requests.
76 $max = 10;
77 for ($i=1; $i <= $max; $i++) {
78 // Build URL to a page that doesn't exist.
79 $url = httprl_build_url_self('asdf-asdf-asdf-' . $i);
80 httprl_request($url, $options);
81 }
82 // Execute requests.
83 $request = httprl_send_request();
84
85 // Echo out the results.
86 echo httprl_pr($request);
87 ?>
88
89
90 Request 10 URLs in a non blocking manner with one httprl_request() call. These
91 URLs will all have the same options.
92
93 <?php
94 // Set the blocking mode.
95 $options = array(
96 'method' => 'HEAD',
97 'blocking' => FALSE,
98 'headers' => array(
99 // Set the Host header to self.
100 'Host' => $_SERVER['HTTP_HOST'],
101 ),
102 );
103 // Queue up the requests.
104 $max = 10;
105 $urls = array();
106 for ($i=1; $i <= $max; $i++) {
107 // Build URL to a page that doesn't exist.
108 $urls[] = httprl_build_url_self('asdf-asdf-asdf-' . $i);
109 }
110 // Queue up the requests.
111 httprl_request($urls, $options);
112 // Execute requests.
113 $request = httprl_send_request();
114
115 // Echo out the results.
116 echo httprl_pr($request);
117 ?>
118
119
120 Request 1000 URLs in a non blocking manner with one httprl_request() call. These
121 URLs will all have the same options. This will saturate the server and any
122 connections that couldn't be made will be dropped.
123
124 <?php
125 // Set the blocking mode.
126 $options = array(
127 'method' => 'HEAD',
128 'blocking' => FALSE,
129 'domain_connections' => 1000,
130 'global_connections' => 1000,
131 'headers' => array(
132 // Set the Host header to self.
133 'Host' => $_SERVER['HTTP_HOST'],
134 ),
135 );
136 // Queue up the requests.
137 $max = 1000;
138 $urls = array();
139 for ($i=1; $i <= $max; $i++) {
140 // Build URL to a page that doesn't exist.
141 $urls[] = httprl_build_url_self('asdf-asdf-asdf-' . $i);
142 }
143 // Queue up the requests.
144 httprl_request($urls, $options);
145 // Execute requests.
146 $request = httprl_send_request();
147
148 // Echo out the results.
149 echo httprl_pr($request);
150 ?>
151
152
153 Request 1000 URLs in a non blocking manner with one httprl_request() call. These
154 URLs will all have the same options. This will saturate the server. Usually all
155 1000 requests will eventually hit the server due to it waiting for the
156 connection to be established; `async_connect` is FALSE.
157
158 <?php
159 // Set the blocking mode.
160 $options = array(
161 'method' => 'HEAD',
162 'blocking' => FALSE,
163 'async_connect' => FALSE,
164 // domain_connections must be smaller than the servers max number of
165 // clients.
166 'domain_connections' => 32,
167 'global_connections' => 1000,
168 'headers' => array(
169 // Set the Host header to self.
170 'Host' => $_SERVER['HTTP_HOST'],
171 ),
172 );
173 // Queue up the requests.
174 $max = 1000;
175 $urls = array();
176 for ($i=1; $i <= $max; $i++) {
177 // Build URL to a page that doesn't exist.
178 $urls[] = httprl_build_url_self('asdf-asdf-asdf-' . $i);
179 }
180 // Queue up the requests.
181 httprl_request($urls, $options);
182 // Execute requests.
183 $request = httprl_send_request();
184
185 // Echo out the results.
186 echo httprl_pr($request);
187 ?>
188
189
190 **HTTP Operations and Callbacks**
191
192 Use a callback in the event loop to do processing on the request. In this case
193 we are going to use httprl_pr() as the callback function.
194
195 <?php
196 // Setup return variable.
197 $x = '';
198 // Setup options array.
199 $options = array(
200 'method' => 'HEAD',
201 'callback' => array(
202 array(
203 'function' => 'httprl_pr',
204 'return' => &$x,
205 ),
206 ),
207 'headers' => array(
208 // Set the Host header to self.
209 'Host' => $_SERVER['HTTP_HOST'],
210 ),
211 );
212 // Build URL to point to front page of this server.
213 $url_front = httprl_build_url_self();
214 // Queue up the request.
215 httprl_request($url_front, $options);
216 // Execute request.
217 $request = httprl_send_request();
218
219 // Echo returned value from function callback.
220 echo $x;
221 ?>
222
223
224 Use a background callback in the event loop to do processing on the request.
225 In this case we are going to use httprl_pr() as the callback function. A
226 background callback creates a new thread to run this function in.
227
228 <?php
229 // Setup return variable.
230 $x = '';
231 // Setup options array.
232 $options = array(
233 'method' => 'HEAD',
234 'background_callback' => array(
235 array(
236 'function' => 'httprl_pr',
237 'return' => &$x,
238 ),
239 ),
240 'headers' => array(
241 // Set the Host header to self.
242 'Host' => $_SERVER['HTTP_HOST'],
243 ),
244 );
245 // Build URL to point to front page of this server.
246 $url_front = httprl_build_url_self();
247 // Queue up the request.
248 httprl_request($url_front, $options);
249 // Execute request.
250 $request = httprl_send_request();
251
252 // Echo returned value from function callback.
253 echo $x;
254 ?>
255
256
257 Use a background callback in the event loop to do processing on the request.
258 In this case we are going to use print_r() as the callback function. A
259 background callback creates a new thread to run this function in. The first
260 argument passed in is the request object, the FALSE tells print_r to echo out
261 instead of returning a value.
262
263 <?php
264 // Setup return & print variable.
265 $x = '';
266 $y = '';
267 // Setup options array.
268 $options = array(
269 'method' => 'HEAD',
270 'background_callback' => array(
271 array(
272 'function' => 'print_r',
273 'return' => &$x,
274 'printed' => &$y,
275 ),
276 FALSE,
277 ),
278 'headers' => array(
279 // Set the Host header to self.
280 'Host' => $_SERVER['HTTP_HOST'],
281 ),
282 );
283 // Build URL to point to front page of this server.
284 $url_front = httprl_build_url_self();
285 // Queue up the request.
286 httprl_request($url_front, $options);
287 // Execute request.
288 $request = httprl_send_request();
289
290 // Echo what was returned and printed from function callback.
291 echo $x . "<br />\n";
292 echo $y;
293 ?>
294
295
296 **More Advanced HTTP Operations**
297
298 Hit 5 different URLs, Using at least 2 that has a status code of 200 and
299 erroring out the others that didn't return fast. Using the Range header so only
300 the first and last 128 bytes are returned.
301
302 <?php
303 // Array of URLs to get.
304 $urls = array(
305 'http://google.com/',
306 'http://bing.com/',
307 'http://yahoo.com/',
308 'http://www.duckduckgo.com/',
309 'http://www.drupal.org/',
310 );
311
312 // Process list of URLs.
313 $options = array(
314 'alter_all_streams_function' => 'need_two_good_results',
315 'headers' => array('Range' => 'bytes=0-127,-128'),
316 );
317 // Queue up the requests.
318 httprl_request($urls, $options);
319
320 // Execute requests.
321 $requests = httprl_send_request();
322
323 // Print what was done.
324 echo httprl_pr($requests);
325
326 function need_two_good_results($id, &$responses) {
327 static $counter = 0;
328 foreach ($responses as $id => &$result) {
329 // Skip if we got a 200 or 206.
330 if ($result->code == 200 || $result->code == 206) {
331 $counter += 1;
332 continue;
333 }
334 if ($result->status == 'Done.') {
335 continue;
336 }
337
338 if ($counter >= 2) {
339 // Set the code to request was aborted.
340 $result->code = HTTPRL_REQUEST_ABORTED;
341 $result->error = 'Software caused connection abort.';
342 // Set status to done and set timeout.
343 $result->status = 'Done.';
344 $result->options['timeout'] -= $result->running_time;
345
346 // Close the file pointer and remove from the stream from the array.
347 fclose($result->fp);
348 unset($result->fp);
349 }
350 }
351 }
352 ?>
353
354
355 Send 2 files in one field via a POST request.
356
357 <?php
358 // Set options.
359 $options = array(
360 'method' => 'POST',
361 'data' => array(
362 'x' => 1,
363 'y' => 2,
364 'z' => 3,
365 'files' => array(
366 'core_js' => array(
367 'misc/form.js',
368 'misc/batch.js',
369 ),
370 ),
371 ),
372 'headers' => array(
373 // Set the Host header to self.
374 'Host' => $_SERVER['HTTP_HOST'],
375 ),
376 );
377 // Send request to front page.
378 $url_front = httprl_build_url_self();
379
380 // Queue up the request.
381 httprl_request($url_front, $options);
382 // Execute request.
383 $request = httprl_send_request();
384 // Echo what was returned.
385 echo httprl_pr($request);
386 ?>
387
388
389 Send out 8 requests. In this example we are going to stall the call to fread()
390 `'stall_fread' => TRUE,`. By doing this we can issue a bunch of requests, do
391 some other stuff and then get the results later on in the PHP process. A useful
392 example would be for ESI emulation. Issue a bunch of requests at the start of
393 the request, generate the main content and then add in the ESI-ed components at
394 the end of the request.
395
396 <?php
397 // Queue up the request.
398 $urls = array(
399 'http://www.google.com/',
400 'http://www.bing.com/',
401 'http://www.yahoo.com/',
402 'http://duckduckgo.com/',
403 'http://drupal.org/',
404 'http://drupal.org/robots.txt',
405 'http://drupal.org/CHANGELOG.txt',
406 'http://drupal.org/MAINTAINERS.txt',
407 );
408 $options = array(
409 // Do fread in a second request.
410 'stall_fread' => TRUE,
411 'headers' => array(
412 // Only grab the last 128 bytes of the request.
413 'Range' => 'bytes=-128',
414 // Accept Compression.
415 'Accept-Encoding' => 'gzip, deflate',
416 ),
417 // Increase the read chunk size to 512KB.
418 'chunk_size_read' => 524288,
419 // Increase domain_connections to 4 (drupal.org).
420 'domain_connections' => 4,
421 // If we can't connect quick (0.5 seconds), bail out.
422 'connect_timeout' => 0.5,
423 'dns_timeout' => 0.5,
424 );
425 httprl_request($urls, $options);
426 // Execute request.
427 echo round(timer_read('page')/1000, 3) . " - Time taken to get requests ready.<br> \n";
428 $request = httprl_send_request();
429 echo strtoupper(var_export($request, TRUE)) . " - Output from first httprl_send_request() call<br> \n";
430
431 echo round(timer_read('page')/1000, 3) . " - Time taken to send out all fwrites().<br> \n";
432 sleep(2);
433 echo round(timer_read('page')/1000, 3) . " - Time taken for sleep(2).<br> \n";
434
435 $request = httprl_send_request();
436 echo round(timer_read('page')/1000, 3) . " - Time taken for all freads().<br> \n";
437 echo "Output from second httprl_send_request() below:<br> \n<br> \n";
438 echo httprl_pr($request);
439 ?>
440
441
442 **Threading Examples**
443
444 Use 2 threads to load up 4 different nodes.
445
446 <?php
447 // Bail out here if background callbacks are disabled.
448 if (!httprl_is_background_callback_capable()) {
449 return FALSE;
450 }
451
452 // List of nodes to load; 241-244.
453 $nodes = array(241 => '', 242 => '', 243 => '', 244 => '');
454 foreach ($nodes as $nid => &$node) {
455 // Setup callback options array.
456 $callback_options = array(
457 array(
458 'function' => 'node_load',
459 'return' => &$node,
460 // Setup options array.
461 'options' => array(
462 'domain_connections' => 2, // Only use 2 threads for this request.
463 ),
464 ),
465 $nid,
466 );
467 // Queue up the request.
468 httprl_queue_background_callback($callback_options);
469 }
470 // Execute request.
471 httprl_send_request();
472
473 // Echo what was returned.
474 echo httprl_pr($nodes);
475 ?>
476
477
478
479 Load nodes 50-100 using httprl_batch_callback and node_load_multiple.
480
481 <?php
482 // List of nodes to load; 50-100.
483 $nids = range(50, 100);
484 // Run not parallel if background callbacks are disabled.
485 if (!httprl_is_background_callback_capable()) {
486 $results = node_load_multiple($nids);
487 }
488 else {
489 // Queue & Execute requests.
490 $results = httprl_batch_callback('node_load_multiple', $nids);
491 }
492 // Echo what was returned.
493 echo httprl_pr($results);
494 ?>
495
496
497
498 Load nodes 50-100 using httprl_batch_callback and node_load.
499
500 <?php
501 // List of nodes to load; 50-100.
502 $nids = range(50, 100);
503 // Run not parallel if background callbacks are disabled.
504 if (!httprl_is_background_callback_capable()) {
505 // httprl_run_multiple does a foreach on $nids running every $value through
506 // the given callback.
507 $results = httprl_run_multiple('node_load', $nids);
508 }
509 else {
510 // Set options.
511 $options = array(
512 'multiple_helper' => TRUE,
513 );
514 // Queue & Execute requests.
515 $results = httprl_batch_callback('node_load', $nids, $options);
516 }
517 // Echo what was returned.
518 echo httprl_pr($results);
519 ?>
520
521
522 Load nodes 50-100 using httprl_batch_callback and node_load_multiple as user 1.
523
524 <?php
525 // List of nodes to load; 50-100.
526 $nids = range(50, 100);
527 // Run not parallel if background callbacks are disabled.
528 if (!httprl_is_background_callback_capable()) {
529 // Run node_load_multiple as user 1
530 $current_account = $GLOBALS['user']->uid;
531 $GLOBALS['user'] = user_load(1);
532 $results = node_load_multiple($nids);
533 // Set global user back.
534 $GLOBALS['user'] = $current_account;
535 }
536 else {
537 // Set options.
538 $options = array(
539 'context' => array(
540 'uid' => 1,
541 ),
542 );
543 // Queue & Execute requests.
544 $results = httprl_batch_callback('node_load_multiple', $nids, $options);
545 }
546 // Echo what was returned.
547 echo httprl_pr($results);
548 ?>
549
550
551
552 Run a function in the background. Notice that there is no return or printed key
553 in the callback options.
554
555 <?php
556 // Bail out here if background callbacks are disabled.
557 if (!httprl_is_background_callback_capable()) {
558 return FALSE;
559 }
560
561 // Setup callback options array; call watchdog in the background.
562 $callback_options = array(
563 array(
564 'function' => 'watchdog',
565 ),
566 'httprl-test', 'background watchdog call done', array(), WATCHDOG_DEBUG,
567 );
568 // Queue up the request.
569 httprl_queue_background_callback($callback_options);
570
571 // Execute request.
572 httprl_send_request();
573 ?>
574
575
576 Pass by reference example. Example is D7 only; pass by reference works in
577 D6 & D7.
578
579 <?php
580 // Code from system_rebuild_module_data().
581 $modules = _system_rebuild_module_data();
582 ksort($modules);
583
584 // Show first module before running system_get_files_database().
585 echo httprl_pr(current($modules));
586
587 // Bail out here if background callbacks are disabled.
588 if (!httprl_is_background_callback_capable()) {
589 return FALSE;
590 }
591
592 $callback_options = array(
593 array(
594 'function' => 'system_get_files_database',
595 'return' => '',
596 ),
597 &$modules, 'module'
598 );
599 httprl_queue_background_callback($callback_options);
600
601 // Execute requests.
602 httprl_send_request();
603
604 // Show first module after running system_get_files_database().
605 echo httprl_pr(current($modules));
606 ?>
607
608
609 Get 2 results from 2 different queries at the hook_boot bootstrap level in D6.
610
611 <?php
612 // Run 2 queries and get the result.
613 $x = db_result(db_query_range("SELECT filename FROM {system} ORDER BY filename ASC", 0, 1));
614 $y = db_result(db_query_range("SELECT filename FROM {system} ORDER BY filename DESC", 0, 1));
615 echo $x . "<br \>\n" . $y . "<br \>\n";
616 unset($x, $y);
617
618
619 // Bail out here if background callbacks are disabled.
620 if (!httprl_is_background_callback_capable()) {
621 return FALSE;
622 }
623
624 // Run above 2 queries and get the result via a background callback.
625 $args = array(
626 // First query.
627 array(
628 'type' => 'function',
629 'call' => 'db_query_range',
630 'args' => array('SELECT filename FROM {system} ORDER BY filename ASC', 0, 1),
631 ),
632 array(
633 'type' => 'function',
634 'call' => 'db_result',
635 'args' => array('last' => NULL),
636 'return' => &$x,
637 ),
638
639 // Second Query.
640 array(
641 'type' => 'function',
642 'call' => 'db_query_range',
643 'args' => array('SELECT filename FROM {system} ORDER BY filename DESC', 0, 1),
644 ),
645 array(
646 'type' => 'function',
647 'call' => 'db_result',
648 'args' => array('last' => NULL),
649 'return' => &$y,
650 ),
651 );
652 $callback_options = array(array('return' => ''), &$args);
653 // Queue up the request.
654 httprl_queue_background_callback($callback_options);
655 // Execute request.
656 httprl_send_request();
657
658 // Echo what was returned.
659 echo httprl_pr($x, $y);
660 ?>
661
662
663 Get 2 results from 2 different queries at the hook_boot bootstrap level in D7.
664
665 <?php
666 $x = db_select('system', 's')
667 ->fields('s', array('filename'))
668 ->orderBy('filename', 'ASC')
669 ->range(0, 1)
670 ->execute()
671 ->fetchField();
672 $y = db_select('system', 's')
673 ->fields('s', array('filename'))
674 ->orderBy('filename', 'DESC')
675 ->range(0, 1)
676 ->execute()
677 ->fetchField();
678 echo $x . "<br \>\n" . $y . "<br \>\n";
679 unset($x, $y);
680
681
682 // Bail out here if background callbacks are disabled.
683 if (!httprl_is_background_callback_capable()) {
684 return FALSE;
685 }
686
687 // Run above 2 queries and get the result via a background callback.
688 $args = array(
689 // First query.
690 array(
691 'type' => 'function',
692 'call' => 'db_select',
693 'args' => array('system', 's',),
694 ),
695 array(
696 'type' => 'method',
697 'call' => 'fields',
698 'args' => array('s', array('filename')),
699 ),
700 array(
701 'type' => 'method',
702 'call' => 'orderBy',
703 'args' => array('filename', 'ASC'),
704 ),
705 array(
706 'type' => 'method',
707 'call' => 'range',
708 'args' => array(0, 1),
709 ),
710 array(
711 'type' => 'method',
712 'call' => 'execute',
713 'args' => array(),
714 ),
715 array(
716 'type' => 'method',
717 'call' => 'fetchField',
718 'args' => array(),
719 'return' => &$x,
720 ),
721
722 // Second Query.
723 array(
724 'type' => 'function',
725 'call' => 'db_select',
726 'args' => array('system', 's',),
727 ),
728 array(
729 'type' => 'method',
730 'call' => 'fields',
731 'args' => array('s', array('filename')),
732 ),
733 array(
734 'type' => 'method',
735 'call' => 'orderBy',
736 'args' => array('filename', 'DESC'),
737 ),
738 array(
739 'type' => 'method',
740 'call' => 'range',
741 'args' => array(0, 1),
742 ),
743 array(
744 'type' => 'method',
745 'call' => 'execute',
746 'args' => array(),
747 ),
748 array(
749 'type' => 'method',
750 'call' => 'fetchField',
751 'args' => array(),
752 'return' => &$y,
753 ),
754 );
755 $callback_options = array(array('return' => ''), &$args);
756 // Queue up the request.
757 httprl_queue_background_callback($callback_options);
758 // Execute request.
759 httprl_send_request();
760
761 // Echo what was returned.
762 echo httprl_pr($x, $y);
763 ?>
764
765
766 Run a cache clear at the DRUPAL_BOOTSTRAP_FULL level as the current user in a
767 non blocking background request.
768
769 <?php
770 // Normal way to do this.
771 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
772 module_load_include('inc', 'system', 'system.admin');
773 system_clear_cache_submit();
774
775
776 // Bail out here if background callbacks are disabled.
777 if (!httprl_is_background_callback_capable()) {
778 return FALSE;
779 }
780
781 // How to do it in a non blocking background request.
782 $args = array(
783 array(
784 'type' => 'function',
785 'call' => 'drupal_bootstrap',
786 'args' => array(DRUPAL_BOOTSTRAP_FULL),
787 ),
788 array(
789 'type' => 'function',
790 'call' => 'module_load_include',
791 'args' => array('inc', 'system', 'system.admin'),
792 ),
793 array(
794 'type' => 'function',
795 'call' => 'system_clear_cache_submit',
796 'args' => array('', ''),
797 ),
798 array(
799 'type' => 'function',
800 'call' => 'watchdog',
801 'args' => array('httprl-test', 'background cache clear done', array(), WATCHDOG_DEBUG),
802 ),
803 );
804
805 // Pass the current session to the sub request.
806 if (!empty($_COOKIE[session_name()])) {
807 $options = array('headers' => array('Cookie' => session_name() . '=' . $_COOKIE[session_name()] . ';'));
808 }
809 else {
810 $options = array();
811 }
812 $callback_options = array(array('options' => $options), &$args);
813
814 // Queue up the request.
815 httprl_queue_background_callback($callback_options);
816 // Execute request.
817 httprl_send_request();
818 ?>
819
820
821 print 'My Text'; cut the connection by sending the data over the wire and do
822 processing in the background.
823
824 <?php
825 httprl_background_processing('My Text');
826 // Everything after this point does not affect page load time.
827 sleep(5);
828 echo 'You should not see this text';
829 ?>