Archive: Namaste PHP AMQP framework v1.0 (2017-2020)
952 days continuous production uptime, 40k+ tp/s single node. Original corpo Bitbucket history not included — clean archive commit.
This commit is contained in:
169
classes/gacWorkQueueClient.class.inc
Normal file
169
classes/gacWorkQueueClient.class.inc
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* this class is used when we want to publish a request to the AdminIn broker. The class wraps all of the
|
||||
* RabbitMQ initialization and communication work so you don't have to. Especially useful for unit testing.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-15-17 mks original coding
|
||||
* 07-07-17 mks CORE-463: updated for async logging (appserver posting log events to admin server)
|
||||
* 07-31-18 mks CORE-774: PHP7.2 exception handling
|
||||
* 01-29-20 mks DB-144: PHP7.4 support
|
||||
* 10-15-20 mks DB-168: renamed, supports all namaste work queues (adminBrokerIn and sBroker)
|
||||
*
|
||||
*/
|
||||
|
||||
use PhpAmqpLib\Channel\AMQPChannel;
|
||||
use PhpAmqpLib\Exception\AMQPRuntimeException;
|
||||
use PhpAmqpLib\Exception\AMQPTimeoutException;
|
||||
use PhpAmqpLib\Message\AMQPMessage;
|
||||
|
||||
class gacWorkQueueClient
|
||||
{
|
||||
private object $rabbitConnection; // actually contains AMQPStreamConnection type but the API declares object|null
|
||||
private ?AMQPChannel $rabbitChannel = null;
|
||||
private ?string $rabbitCallbackQueue;
|
||||
private ?string $rabbitResponse;
|
||||
private string $rabbitCorrelationID;
|
||||
private string $queueName;
|
||||
|
||||
public bool $status;
|
||||
|
||||
/**
|
||||
* __construct() -- public method
|
||||
*
|
||||
* this is the constructor for the class. it requests an admin resource from the resource manager and declares
|
||||
* a client-side connection to the service.
|
||||
*
|
||||
* there is an optional input parameter -- $_fw (from-where) that inserts a string into the queue label allowing
|
||||
* easy identification of the requesting source.
|
||||
*
|
||||
* the method returns no values. It only sets the class' status member variable, a Boolean, on success or fail,
|
||||
* accordingly.
|
||||
*
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* @param $_fw - "from where" - tweaks queue label to identify request origin
|
||||
* @param $_which - which fire-n-forget broker queue to attache to (default is adminIn)
|
||||
*
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-15-17 mks original coding
|
||||
* 05-31-18 mks CORE-1011: update for new XML broker services configuration
|
||||
* 05-31-18 mks CORE-1011: update for new XML broker services configuration
|
||||
* 09-19-19 mks DB-136: improved exception handling
|
||||
* 10-02-20 mks DB-168: support for (new) session broker (also fire-n-forget), removed callback method
|
||||
*
|
||||
*/
|
||||
public function __construct(string $_fw = __METHOD__ . AT . __LINE__, string $_which = BROKER_QUEUE_AI)
|
||||
{
|
||||
register_shutdown_function(array($this, STRING_DESTRUCTOR));
|
||||
$this->status = false;
|
||||
|
||||
switch ($_which) {
|
||||
case BROKER_QUEUE_AI :
|
||||
$resource = RESOURCE_ADMIN;
|
||||
$queue = BROKER_QUEUE_AI;
|
||||
$labelClient = 'gacAdminInClient<';
|
||||
break;
|
||||
case BROKER_QUEUE_S :
|
||||
$resource = RESOURCE_TERCERO;
|
||||
$queue = BROKER_QUEUE_S;
|
||||
$labelClient = 'gacSessionClient<';
|
||||
break;
|
||||
default :
|
||||
consoleLog('cACI: ', CON_ERROR, ERROR_CONFIG_RESOURCE_404 . $_which);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->queueName = gasConfig::$settings[CONFIG_BROKER_SERVICES][CONFIG_BROKER_QUEUE_TAG] . $queue;
|
||||
try {
|
||||
$this->rabbitConnection = gasResourceManager::fetchResource($resource);
|
||||
if (is_null($this->rabbitConnection)) return;
|
||||
$this->rabbitChannel = $this->rabbitConnection->channel();
|
||||
$label = uniqid($labelClient . $_fw . '>:');
|
||||
list($this->rabbitCallbackQueue, ,) = $this->rabbitChannel->queue_declare($label . uniqid(), false, false, false, true);
|
||||
$this->rabbitChannel->basic_consume($this->rabbitCallbackQueue, '', false, true, false, false);
|
||||
$this->rabbitResponse = null;
|
||||
$this->status = true;
|
||||
} catch (AMQPRuntimeException | AMQPTimeoutException | Throwable | TypeError $t) {
|
||||
$hdr = basename(__METHOD__) . AT . __LINE__ . COLON;
|
||||
@handleExceptionMessaging($hdr, $t->getMessage(), $foo, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* call() -- public method
|
||||
*
|
||||
* This method is invoked outside of the class and is the entry point for publishing a message request to the
|
||||
* AdminIn broker. It creates a new AMQP message and publishes it to the queue (defined in the constructor),
|
||||
* and then exits, returning a true message indicating that the messages was successfully published.
|
||||
*
|
||||
* Since the AdminIN broker is a fire-n-forget broker, there are no return messages to block-and-wait on.
|
||||
*
|
||||
* If an exception is raised by this class, then a false value will be returned.
|
||||
*
|
||||
* NOTE: the true/false return values are not, in any way, a reflection of the processing success/failure on the
|
||||
* remote service. The general RoT is that if we can publish the request, then we can only assume that the request
|
||||
* was successfully consumed and processed.
|
||||
*
|
||||
* @author mike@givingassistant.org
|
||||
* @version 1.0
|
||||
*
|
||||
* @param $_data
|
||||
* @return bool
|
||||
*
|
||||
* HISTORY:
|
||||
* ========
|
||||
* 06-15-17 mks original coding
|
||||
* 08-17-17 mks CORE-500: returning a boolean that actually indicates if we successfully published the event
|
||||
* 09-19-19 mks DB-136: refactored exception handling, fixed the AMQPMessage create call
|
||||
* 10-20-20 mks DB-168: better exception handling, removed channel close b/c autodelete is on
|
||||
*
|
||||
*/
|
||||
public function call($_data): bool
|
||||
{
|
||||
$this->rabbitResponse = null;
|
||||
$this->rabbitCorrelationID = uniqid();
|
||||
$success = false;
|
||||
|
||||
try {
|
||||
$rabbitMessage = new AMQPMessage((string)$_data);
|
||||
$this->rabbitChannel->basic_publish($rabbitMessage, '', $this->queueName);
|
||||
$success = true;
|
||||
} catch (AMQPTimeoutException | AMQPRuntimeException | Throwable $e) {
|
||||
$hdr = basename(__METHOD__) . AT . __LINE__ . COLON;
|
||||
@handleExceptionMessaging($hdr, $e->getMessage(), $foo, true);
|
||||
}
|
||||
return ($success);
|
||||
}
|
||||
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
// As of PHP 5.3.10 destructors are not run on shutdown caused by fatal errors.
|
||||
//
|
||||
// destructor is registered shut-down function in constructor -- so any recovery
|
||||
// efforts should go in this method.
|
||||
try {
|
||||
if (!is_null($this->rabbitChannel)) {
|
||||
$this->rabbitChannel->close();
|
||||
$this->rabbitConnection->close();
|
||||
}
|
||||
} catch (AMQPRuntimeException | AMQPTimeoutException | Throwable | TypeError $t) {
|
||||
$hdr = basename(__METHOD__) . AT . __LINE__ . COLON;
|
||||
@handleExceptionMessaging($hdr, $t->getMessage(), $foo, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user