Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
13815 anikendra 1
<?php
2
/**
3
 * Copyright (c) 2007-2011, Servigistics, Inc.
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are met:
8
 *
9
 *  - Redistributions of source code must retain the above copyright notice,
10
 *    this list of conditions and the following disclaimer.
11
 *  - Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *  - Neither the name of Servigistics, Inc. nor the names of
15
 *    its contributors may be used to endorse or promote products derived from
16
 *    this software without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * @copyright Copyright 2007-2011 Servigistics, Inc. (http://servigistics.com)
31
 * @license http://solr-php-client.googlecode.com/svn/trunk/COPYING New BSD
32
 * @version $Id: Balancer.php 54 2011-02-04 16:29:18Z donovan.jimenez $
33
 *
34
 * @package Apache
35
 * @subpackage Solr
36
 * @author Donovan Jimenez <djimenez@conduit-it.com>, Dan Wolfe
37
 */
38
 
39
// See Issue #1 (http://code.google.com/p/solr-php-client/issues/detail?id=1)
40
// Doesn't follow typical include path conventions, but is more convenient for users
41
require_once(dirname(dirname(__FILE__)) . '/Service.php');
42
 
43
require_once(dirname(dirname(__FILE__)) . '/NoServiceAvailableException.php');
44
 
45
/**
46
 * Reference Implementation for using multiple Solr services in a distribution. Functionality
47
 * includes:
48
 * 	routing of read / write operations
49
 * 	failover (on selection) for multiple read servers
50
 */
51
class Apache_Solr_Service_Balancer
52
{
53
	/**
54
	 * SVN Revision meta data for this class
55
	 */
56
	const SVN_REVISION = '$Revision: 54 $';
57
 
58
	/**
59
	 * SVN ID meta data for this class
60
	 */
61
	const SVN_ID = '$Id: Balancer.php 54 2011-02-04 16:29:18Z donovan.jimenez $';
62
 
63
	protected $_createDocuments = true;
64
 
65
	protected $_readableServices = array();
66
	protected $_writeableServices = array();
67
 
68
	protected $_currentReadService = null;
69
	protected $_currentWriteService = null;
70
 
71
	protected $_readPingTimeout = 2;
72
	protected $_writePingTimeout = 4;
73
 
74
	// Configuration for server selection backoff intervals
75
	protected $_useBackoff = false;		// Set to true to use more resillient write server selection
76
	protected $_backoffLimit = 600;		// 10 minute default maximum
77
	protected $_backoffEscalation = 2.0; 	// Rate at which to increase backoff period
78
	protected $_defaultBackoff = 2.0;		// Default backoff interval
79
 
80
	/**
81
	 * Escape a value for special query characters such as ':', '(', ')', '*', '?', etc.
82
	 *
83
	 * NOTE: inside a phrase fewer characters need escaped, use {@link Apache_Solr_Service::escapePhrase()} instead
84
	 *
85
	 * @param string $value
86
	 * @return string
87
	 */
88
	static public function escape($value)
89
	{
90
		return Apache_Solr_Service::escape($value);
91
	}
92
 
93
	/**
94
	 * Escape a value meant to be contained in a phrase for special query characters
95
	 *
96
	 * @param string $value
97
	 * @return string
98
	 */
99
	static public function escapePhrase($value)
100
	{
101
		return Apache_Solr_Service::escapePhrase($value);
102
	}
103
 
104
	/**
105
	 * Convenience function for creating phrase syntax from a value
106
	 *
107
	 * @param string $value
108
	 * @return string
109
	 */
110
	static public function phrase($value)
111
	{
112
		return Apache_Solr_Service::phrase($value);
113
	}
114
 
115
	/**
116
	 * Constructor. Takes arrays of read and write service instances or descriptions
117
	 *
118
	 * @param array $readableServices
119
	 * @param array $writeableServices
120
	 */
121
	public function __construct($readableServices = array(), $writeableServices = array())
122
	{
123
		//setup readable services
124
		foreach ($readableServices as $service)
125
		{
126
			$this->addReadService($service);
127
		}
128
 
129
		//setup writeable services
130
		foreach ($writeableServices as $service)
131
		{
132
			$this->addWriteService($service);
133
		}
134
	}
135
 
136
	public function setReadPingTimeout($timeout)
137
	{
138
		$this->_readPingTimeout = $timeout;
139
	}
140
 
141
	public function setWritePingTimeout($timeout)
142
	{
143
		$this->_writePingTimeout = $timeout;
144
	}
145
 
146
	public function setUseBackoff($enable)
147
	{
148
		$this->_useBackoff = $enable;
149
	}
150
 
151
	/**
152
	 * Generates a service ID
153
	 *
154
	 * @param string $host
155
	 * @param integer $port
156
	 * @param string $path
157
	 * @return string
158
	 */
159
	protected function _getServiceId($host, $port, $path)
160
	{
161
		return $host . ':' . $port . $path;
162
	}
163
 
164
	/**
165
	 * Adds a service instance or service descriptor (if it is already
166
	 * not added)
167
	 *
168
	 * @param mixed $service
169
	 *
170
	 * @throws Apache_Solr_InvalidArgumentException If service descriptor is not valid
171
	 */
172
	public function addReadService($service)
173
	{
174
		if ($service instanceof Apache_Solr_Service)
175
		{
176
			$id = $this->_getServiceId($service->getHost(), $service->getPort(), $service->getPath());
177
 
178
			$this->_readableServices[$id] = $service;
179
		}
180
		else if (is_array($service))
181
		{
182
			if (isset($service['host']) && isset($service['port']) && isset($service['path']))
183
			{
184
				$id = $this->_getServiceId((string)$service['host'], (int)$service['port'], (string)$service['path']);
185
 
186
				$this->_readableServices[$id] = $service;
187
			}
188
			else
189
			{
190
				throw new Apache_Solr_InvalidArgumentException('A Readable Service description array does not have all required elements of host, port, and path');
191
			}
192
		}
193
	}
194
 
195
	/**
196
	 * Removes a service instance or descriptor from the available services
197
	 *
198
	 * @param mixed $service
199
	 *
200
	 * @throws Apache_Solr_InvalidArgumentException If service descriptor is not valid
201
	 */
202
	public function removeReadService($service)
203
	{
204
		$id = '';
205
 
206
		if ($service instanceof Apache_Solr_Service)
207
		{
208
			$id = $this->_getServiceId($service->getHost(), $service->getPort(), $service->getPath());
209
		}
210
		else if (is_array($service))
211
		{
212
			if (isset($service['host']) && isset($service['port']) && isset($service['path']))
213
			{
214
				$id = $this->_getServiceId((string)$service['host'], (int)$service['port'], (string)$service['path']);
215
			}
216
			else
217
			{
218
				throw new Apache_Solr_InvalidArgumentException('A Readable Service description array does not have all required elements of host, port, and path');
219
			}
220
		}
221
		else if (is_string($service))
222
		{
223
			$id = $service;
224
		}
225
 
226
		if ($id && isset($this->_readableServices[$id]))
227
		{
228
			unset($this->_readableServices[$id]);
229
		}
230
	}
231
 
232
	/**
233
	 * Adds a service instance or service descriptor (if it is already
234
	 * not added)
235
	 *
236
	 * @param mixed $service
237
	 *
238
	 * @throws Apache_Solr_InvalidArgumentException If service descriptor is not valid
239
	 */
240
	public function addWriteService($service)
241
	{
242
		if ($service instanceof Apache_Solr_Service)
243
		{
244
			$id = $this->_getServiceId($service->getHost(), $service->getPort(), $service->getPath());
245
 
246
			$this->_writeableServices[$id] = $service;
247
		}
248
		else if (is_array($service))
249
		{
250
			if (isset($service['host']) && isset($service['port']) && isset($service['path']))
251
			{
252
				$id = $this->_getServiceId((string)$service['host'], (int)$service['port'], (string)$service['path']);
253
 
254
				$this->_writeableServices[$id] = $service;
255
			}
256
			else
257
			{
258
				throw new Apache_Solr_InvalidArgumentException('A Writeable Service description array does not have all required elements of host, port, and path');
259
			}
260
		}
261
	}
262
 
263
	/**
264
	 * Removes a service instance or descriptor from the available services
265
	 *
266
	 * @param mixed $service
267
	 *
268
	 * @throws Apache_Solr_InvalidArgumentException If service descriptor is not valid
269
	 */
270
	public function removeWriteService($service)
271
	{
272
		$id = '';
273
 
274
		if ($service instanceof Apache_Solr_Service)
275
		{
276
			$id = $this->_getServiceId($service->getHost(), $service->getPort(), $service->getPath());
277
		}
278
		else if (is_array($service))
279
		{
280
			if (isset($service['host']) && isset($service['port']) && isset($service['path']))
281
			{
282
				$id = $this->_getServiceId((string)$service['host'], (int)$service['port'], (string)$service['path']);
283
			}
284
			else
285
			{
286
				throw new Apache_Solr_InvalidArgumentException('A Readable Service description array does not have all required elements of host, port, and path');
287
			}
288
		}
289
		else if (is_string($service))
290
		{
291
			$id = $service;
292
		}
293
 
294
		if ($id && isset($this->_writeableServices[$id]))
295
		{
296
			unset($this->_writeableServices[$id]);
297
		}
298
	}
299
 
300
	/**
301
	 * Iterate through available read services and select the first with a ping
302
	 * that satisfies configured timeout restrictions (or the default)
303
	 *
304
	 * @return Apache_Solr_Service
305
	 *
306
	 * @throws Apache_Solr_NoServiceAvailableException If there are no read services that meet requirements
307
	 */
308
	protected function _selectReadService($forceSelect = false)
309
	{
310
		if (!$this->_currentReadService || !isset($this->_readableServices[$this->_currentReadService]) || $forceSelect)
311
		{
312
			if ($this->_currentReadService && isset($this->_readableServices[$this->_currentReadService]) && $forceSelect)
313
			{
314
				// we probably had a communication error, ping the current read service, remove it if it times out
315
				if ($this->_readableServices[$this->_currentReadService]->ping($this->_readPingTimeout) === false)
316
				{
317
					$this->removeReadService($this->_currentReadService);
318
				}
319
			}
320
 
321
			if (count($this->_readableServices))
322
			{
323
				// select one of the read services at random
324
				$ids = array_keys($this->_readableServices);
325
 
326
				$id = $ids[rand(0, count($ids) - 1)];
327
				$service = $this->_readableServices[$id];
328
 
329
				if (is_array($service))
330
				{
331
					//convert the array definition to a client object
332
					$service = new Apache_Solr_Service($service['host'], $service['port'], $service['path']);
333
					$this->_readableServices[$id] = $service;
334
				}
335
 
336
				$service->setCreateDocuments($this->_createDocuments);
337
				$this->_currentReadService = $id;
338
			}
339
			else
340
			{
341
				throw new Apache_Solr_NoServiceAvailableException('No read services were available');
342
			}
343
		}
344
 
345
		return $this->_readableServices[$this->_currentReadService];
346
	}
347
 
348
	/**
349
	 * Iterate through available write services and select the first with a ping
350
	 * that satisfies configured timeout restrictions (or the default)
351
	 *
352
	 * @return Apache_Solr_Service
353
	 *
354
	 * @throws Apache_Solr_NoServiceAvailableException If there are no write services that meet requirements
355
	 */
356
	protected function _selectWriteService($forceSelect = false)
357
	{
358
		if($this->_useBackoff)
359
		{
360
			return $this->_selectWriteServiceSafe($forceSelect);
361
		}
362
 
363
		if (!$this->_currentWriteService || !isset($this->_writeableServices[$this->_currentWriteService]) || $forceSelect)
364
		{
365
			if ($this->_currentWriteService && isset($this->_writeableServices[$this->_currentWriteService]) && $forceSelect)
366
			{
367
				// we probably had a communication error, ping the current read service, remove it if it times out
368
				if ($this->_writeableServices[$this->_currentWriteService]->ping($this->_writePingTimeout) === false)
369
				{
370
					$this->removeWriteService($this->_currentWriteService);
371
				}
372
			}
373
 
374
			if (count($this->_writeableServices))
375
			{
376
				// select one of the read services at random
377
				$ids = array_keys($this->_writeableServices);
378
 
379
				$id = $ids[rand(0, count($ids) - 1)];
380
				$service = $this->_writeableServices[$id];
381
 
382
				if (is_array($service))
383
				{
384
					//convert the array definition to a client object
385
					$service = new Apache_Solr_Service($service['host'], $service['port'], $service['path']);
386
					$this->_writeableServices[$id] = $service;
387
				}
388
 
389
				$this->_currentWriteService = $id;
390
			}
391
			else
392
			{
393
				throw new Apache_Solr_NoServiceAvailableException('No write services were available');
394
			}
395
		}
396
 
397
		return $this->_writeableServices[$this->_currentWriteService];
398
	}
399
 
400
	/**
401
	 * Iterate through available write services and select the first with a ping
402
	 * that satisfies configured timeout restrictions (or the default).  The
403
	 * timeout period will increase until a connection is made or the limit is
404
	 * reached.   This will allow for increased reliability with heavily loaded
405
	 * server(s).
406
	 *
407
	 * @return Apache_Solr_Service
408
	 *
409
	 * @throws Apache_Solr_NoServiceAvailableException If there are no write services that meet requirements
410
	 */
411
 
412
	protected function _selectWriteServiceSafe($forceSelect = false)
413
	{
414
		if (!$this->_currentWriteService || !isset($this->_writeableServices[$this->_currentWriteService]) || $forceSelect)
415
		{
416
			if (count($this->_writeableServices))
417
			{
418
				$backoff = $this->_defaultBackoff;
419
 
420
				do {
421
					// select one of the read services at random
422
					$ids = array_keys($this->_writeableServices);
423
 
424
					$id = $ids[rand(0, count($ids) - 1)];
425
					$service = $this->_writeableServices[$id];
426
 
427
					if (is_array($service))
428
					{
429
						//convert the array definition to a client object
430
						$service = new Apache_Solr_Service($service['host'], $service['port'], $service['path']);
431
						$this->_writeableServices[$id] = $service;
432
					}
433
 
434
					$this->_currentWriteService = $id;
435
 
436
					$backoff *= $this->_backoffEscalation;
437
 
438
					if($backoff > $this->_backoffLimit)
439
					{
440
						throw new Apache_Solr_NoServiceAvailableException('No write services were available.  All timeouts exceeded.');
441
					}
442
 
443
				} while($this->_writeableServices[$this->_currentWriteService]->ping($backoff) === false);
444
			}
445
			else
446
			{
447
				throw new Apache_Solr_NoServiceAvailableException('No write services were available');
448
			}
449
		}
450
 
451
		return $this->_writeableServices[$this->_currentWriteService];
452
	}
453
 
454
	/**
455
	 * Set the create documents flag. This determines whether {@link Apache_Solr_Response} objects will
456
	 * parse the response and create {@link Apache_Solr_Document} instances in place.
457
	 *
458
	 * @param boolean $createDocuments
459
	 */
460
	public function setCreateDocuments($createDocuments)
461
	{
462
		$this->_createDocuments = (bool) $createDocuments;
463
 
464
		// set on current read service
465
		if ($this->_currentReadService)
466
		{
467
			$service = $this->_selectReadService();
468
			$service->setCreateDocuments($createDocuments);
469
		}
470
	}
471
 
472
	/**
473
	 * Get the current state of teh create documents flag.
474
	 *
475
	 * @return boolean
476
	 */
477
	public function getCreateDocuments()
478
	{
479
		return $this->_createDocuments;
480
	}
481
 
482
	/**
483
	 * Raw Add Method. Takes a raw post body and sends it to the update service.  Post body
484
	 * should be a complete and well formed "add" xml document.
485
	 *
486
	 * @param string $rawPost
487
	 * @return Apache_Solr_Response
488
	 *
489
	 * @throws Apache_Solr_HttpTransportException If an error occurs during the service call
490
	 */
491
	public function add($rawPost)
492
	{
493
		$service = $this->_selectWriteService();
494
 
495
		do
496
		{
497
			try
498
			{
499
				return $service->add($rawPost);
500
			}
501
			catch (Apache_Solr_HttpTransportException $e)
502
			{
503
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
504
				{
505
					throw $e;
506
				}
507
			}
508
 
509
			$service = $this->_selectWriteService(true);
510
		} while ($service);
511
 
512
		return false;
513
	}
514
 
515
	/**
516
	 * Add a Solr Document to the index
517
	 *
518
	 * @param Apache_Solr_Document $document
519
	 * @param boolean $allowDups
520
	 * @param boolean $overwritePending
521
	 * @param boolean $overwriteCommitted
522
	 * @return Apache_Solr_Response
523
	 *
524
	 * @throws Apache_Solr_HttpTransportException If an error occurs during the service call
525
	 */
526
	public function addDocument(Apache_Solr_Document $document, $allowDups = false, $overwritePending = true, $overwriteCommitted = true)
527
	{
528
		$service = $this->_selectWriteService();
529
 
530
		do
531
		{
532
			try
533
			{
534
				return $service->addDocument($document, $allowDups, $overwritePending, $overwriteCommitted);
535
			}
536
			catch (Apache_Solr_HttpTransportException $e)
537
			{
538
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
539
				{
540
					throw $e;
541
				}
542
			}
543
 
544
			$service = $this->_selectWriteService(true);
545
		} while ($service);
546
 
547
		return false;
548
	}
549
 
550
	/**
551
	 * Add an array of Solr Documents to the index all at once
552
	 *
553
	 * @param array $documents Should be an array of Apache_Solr_Document instances
554
	 * @param boolean $allowDups
555
	 * @param boolean $overwritePending
556
	 * @param boolean $overwriteCommitted
557
	 * @return Apache_Solr_Response
558
	 *
559
	 * @throws Apache_Solr_HttpTransportException If an error occurs during the service call
560
	 */
561
	public function addDocuments($documents, $allowDups = false, $overwritePending = true, $overwriteCommitted = true)
562
	{
563
		$service = $this->_selectWriteService();
564
 
565
		do
566
		{
567
			try
568
			{
569
				return $service->addDocuments($documents, $allowDups, $overwritePending, $overwriteCommitted);
570
			}
571
			catch (Apache_Solr_HttpTransportException $e)
572
			{
573
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
574
				{
575
					throw $e;
576
				}
577
			}
578
 
579
			$service = $this->_selectWriteService(true);
580
		} while ($service);
581
 
582
		return false;
583
	}
584
 
585
	/**
586
	 * Send a commit command.  Will be synchronous unless both wait parameters are set
587
	 * to false.
588
	 *
589
	 * @param boolean $waitFlush
590
	 * @param boolean $waitSearcher
591
	 * @return Apache_Solr_Response
592
	 *
593
	 * @throws Apache_Solr_HttpTransportException If an error occurs during the service call
594
	 */
595
	public function commit($optimize = true, $waitFlush = true, $waitSearcher = true, $timeout = 3600)
596
	{
597
		$service = $this->_selectWriteService();
598
 
599
		do
600
		{
601
			try
602
			{
603
				return $service->commit($optimize, $waitFlush, $waitSearcher, $timeout);
604
			}
605
			catch (Apache_Solr_HttpTransportException $e)
606
			{
607
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
608
				{
609
					throw $e;
610
				}
611
			}
612
 
613
			$service = $this->_selectWriteService(true);
614
		} while ($service);
615
 
616
		return false;
617
	}
618
 
619
	/**
620
	 * Raw Delete Method. Takes a raw post body and sends it to the update service. Body should be
621
	 * a complete and well formed "delete" xml document
622
	 *
623
	 * @param string $rawPost
624
	 * @param float $timeout Maximum expected duration of the delete operation on the server (otherwise, will throw a communication exception)
625
	 * @return Apache_Solr_Response
626
	 *
627
	 * @throws Apache_Solr_HttpTransportException If an error occurs during the service call
628
	 */
629
	public function delete($rawPost, $timeout = 3600)
630
	{
631
		$service = $this->_selectWriteService();
632
 
633
		do
634
		{
635
			try
636
			{
637
				return $service->delete($rawPost, $timeout);
638
			}
639
			catch (Apache_Solr_HttpTransportException $e)
640
			{
641
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
642
				{
643
					throw $e;
644
				}
645
			}
646
 
647
			$service = $this->_selectWriteService(true);
648
		} while ($service);
649
 
650
		return false;
651
	}
652
 
653
	/**
654
	 * Create a delete document based on document ID
655
	 *
656
	 * @param string $id
657
	 * @param boolean $fromPending
658
	 * @param boolean $fromCommitted
659
	 * @param float $timeout Maximum expected duration of the delete operation on the server (otherwise, will throw a communication exception)
660
	 * @return Apache_Solr_Response
661
	 *
662
	 * @throws Apache_Solr_HttpTransportException If an error occurs during the service call
663
	 */
664
	public function deleteById($id, $fromPending = true, $fromCommitted = true, $timeout = 3600)
665
	{
666
		$service = $this->_selectWriteService();
667
 
668
		do
669
		{
670
			try
671
			{
672
				return $service->deleteById($id, $fromPending, $fromCommitted, $timeout);
673
			}
674
			catch (Apache_Solr_HttpTransportException $e)
675
			{
676
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
677
				{
678
					throw $e;
679
				}
680
			}
681
 
682
			$service = $this->_selectWriteService(true);
683
		} while ($service);
684
 
685
		return false;
686
	}
687
 
688
	/**
689
	 * Create and post a delete document based on multiple document IDs.
690
	 *
691
	 * @param array $ids Expected to be utf-8 encoded strings
692
	 * @param boolean $fromPending
693
	 * @param boolean $fromCommitted
694
	 * @param float $timeout Maximum expected duration of the delete operation on the server (otherwise, will throw a communication exception)
695
	 * @return Apache_Solr_Response
696
	 *
697
	 * @throws Apache_Solr_HttpTransportException If an error occurs during the service call
698
	 */
699
	public function deleteByMultipleIds($ids, $fromPending = true, $fromCommitted = true, $timeout = 3600)
700
	{
701
		$service = $this->_selectWriteService();
702
 
703
		do
704
		{
705
			try
706
			{
707
				return $service->deleteByMultipleId($ids, $fromPending, $fromCommitted, $timeout);
708
			}
709
			catch (Apache_Solr_HttpTransportException $e)
710
			{
711
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
712
				{
713
					throw $e;
714
				}
715
			}
716
 
717
			$service = $this->_selectWriteService(true);
718
		} while ($service);
719
 
720
		return false;
721
	}
722
 
723
	/**
724
	 * Create a delete document based on a query and submit it
725
	 *
726
	 * @param string $rawQuery
727
	 * @param boolean $fromPending
728
	 * @param boolean $fromCommitted
729
	 * @param float $timeout Maximum expected duration of the delete operation on the server (otherwise, will throw a communication exception)
730
	 * @return Apache_Solr_Response
731
	 *
732
	 * @throws Apache_Solr_HttpTransportException If an error occurs during the service call
733
	 */
734
	public function deleteByQuery($rawQuery, $fromPending = true, $fromCommitted = true, $timeout = 3600)
735
	{
736
		$service = $this->_selectWriteService();
737
 
738
		do
739
		{
740
			try
741
			{
742
				return $service->deleteByQuery($rawQuery, $fromPending, $fromCommitted, $timeout);
743
			}
744
			catch (Apache_Solr_HttpTransportException $e)
745
			{
746
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
747
				{
748
					throw $e;
749
				}
750
			}
751
 
752
			$service = $this->_selectWriteService(true);
753
		} while ($service);
754
 
755
		return false;
756
	}
757
 
758
	/**
759
	 * Use Solr Cell to extract document contents. See {@link http://wiki.apache.org/solr/ExtractingRequestHandler} for information on how
760
	 * to use Solr Cell and what parameters are available.
761
	 *
762
	 * NOTE: when passing an Apache_Solr_Document instance, field names and boosts will automatically be prepended by "literal." and "boost."
763
	 * as appropriate. Any keys from the $params array will NOT be treated this way. Any mappings from the document will overwrite key / value
764
	 * pairs in the params array if they have the same name (e.g. you pass a "literal.id" key and value in your $params array but you also
765
	 * pass in a document isntance with an "id" field" - the document's value(s) will take precedence).
766
	 *
767
	 * @param string $file Path to file to extract data from
768
	 * @param array $params optional array of key value pairs that will be sent with the post (see Solr Cell documentation)
769
	 * @param Apache_Solr_Document $document optional document that will be used to generate post parameters (literal.* and boost.* params)
770
	 * @param string $mimetype optional mimetype specification (for the file being extracted)
771
	 *
772
	 * @return Apache_Solr_Response
773
	 *
774
	 * @throws Apache_Solr_InvalidArgumentException if $file, $params, or $document are invalid.
775
	 */
776
	public function extract($file, $params = array(), $document = null, $mimetype = 'application/octet-stream')
777
	{
778
		$service = $this->_selectWriteService();
779
 
780
		do
781
		{
782
			try
783
			{
784
				return $service->extract($file, $params, $document, $mimetype);
785
			}
786
			catch (Apache_Solr_HttpTransportException $e)
787
			{
788
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
789
				{
790
					throw $e;
791
				}
792
			}
793
 
794
			$service = $this->_selectWriteService(true);
795
		} while ($service);
796
 
797
		return false;
798
	}
799
 
800
	/**
801
	 * Use Solr Cell to extract document contents. See {@link http://wiki.apache.org/solr/ExtractingRequestHandler} for information on how
802
	 * to use Solr Cell and what parameters are available.
803
	 *
804
	 * NOTE: when passing an Apache_Solr_Document instance, field names and boosts will automatically be prepended by "literal." and "boost."
805
	 * as appropriate. Any keys from the $params array will NOT be treated this way. Any mappings from the document will overwrite key / value
806
	 * pairs in the params array if they have the same name (e.g. you pass a "literal.id" key and value in your $params array but you also
807
	 * pass in a document isntance with an "id" field" - the document's value(s) will take precedence).
808
	 *
809
	 * @param string $data Data that will be passed to Solr Cell
810
	 * @param array $params optional array of key value pairs that will be sent with the post (see Solr Cell documentation)
811
	 * @param Apache_Solr_Document $document optional document that will be used to generate post parameters (literal.* and boost.* params)
812
	 * @param string $mimetype optional mimetype specification (for the file being extracted)
813
	 *
814
	 * @return Apache_Solr_Response
815
	 *
816
	 * @throws Apache_Solr_InvalidArgumentException if $file, $params, or $document are invalid.
817
	 *
818
	 * @todo Should be using multipart/form-data to post parameter values, but I could not get my implementation to work. Needs revisisted.
819
	 */
820
	public function extractFromString($data, $params = array(), $document = null, $mimetype = 'application/octet-stream')
821
	{
822
		$service = $this->_selectWriteService();
823
 
824
		do
825
		{
826
			try
827
			{
828
				return $service->extractFromString($data, $params, $document, $mimetype);
829
			}
830
			catch (Apache_Solr_HttpTransportException $e)
831
			{
832
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
833
				{
834
					throw $e;
835
				}
836
			}
837
 
838
			$service = $this->_selectWriteService(true);
839
		} while ($service);
840
 
841
		return false;
842
	}
843
 
844
	/**
845
	 * Send an optimize command.  Will be synchronous unless both wait parameters are set
846
	 * to false.
847
	 *
848
	 * @param boolean $waitFlush
849
	 * @param boolean $waitSearcher
850
	 * @param float $timeout Maximum expected duration of the optimize operation on the server (otherwise, will throw a communication exception)
851
	 * @return Apache_Solr_Response
852
	 *
853
	 * @throws Apache_Solr_HttpTransportException If an error occurs during the service call
854
	 */
855
	public function optimize($waitFlush = true, $waitSearcher = true, $timeout = 3600)
856
	{
857
		$service = $this->_selectWriteService();
858
 
859
		do
860
		{
861
			try
862
			{
863
				return $service->optimize($waitFlush, $waitSearcher, $timeout);
864
			}
865
			catch (Apache_Solr_HttpTransportException $e)
866
			{
867
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
868
				{
869
					throw $e;
870
				}
871
			}
872
 
873
			$service = $this->_selectWriteService(true);
874
		} while ($service);
875
 
876
		return false;
877
	}
878
 
879
	/**
880
	 * Simple Search interface
881
	 *
882
	 * @param string $query The raw query string
883
	 * @param int $offset The starting offset for result documents
884
	 * @param int $limit The maximum number of result documents to return
885
	 * @param array $params key / value pairs for query parameters, use arrays for multivalued parameters
886
	 * @param string $method The HTTP method (Apache_Solr_Service::METHOD_GET or Apache_Solr_Service::METHOD::POST)
887
	 * @return Apache_Solr_Response
888
	 *
889
	 * @throws Apache_Solr_HttpTransportException If an error occurs during the service call
890
	 */
891
	public function search($query, $offset = 0, $limit = 10, $params = array(), $method = Apache_Solr_Service::METHOD_GET)
892
	{
893
		$service = $this->_selectReadService();
894
 
895
		do
896
		{
897
			try
898
			{
899
				return $service->search($query, $offset, $limit, $params, $method);
900
			}
901
			catch (Apache_Solr_HttpTransportException $e)
902
			{
903
				if ($e->getCode() != 0) //IF NOT COMMUNICATION ERROR
904
				{
905
					throw $e;
906
				}
907
			}
908
 
909
			$service = $this->_selectReadService(true);
910
		} while ($service);
911
 
912
		return false;
913
	}
914
}