<?php
// ---- that factory map we were talking about
class DispatchMap
{
/**
* @var array Hardcoded mapping of executable type to dispatch strategy
*/
private $mapping = [
QueueExecutable::class => QueueExecutableDispatcher::class,
ProcessExecutable::class => ProcessExecutableDispatcher::class
];
/**
* @param Executable $executable
*
* @throws \RuntimeException
*
* @return DispatchStrategy
*/
public function getDispatcherForExecutable(Executable $executable): DispatchStrategy
{
if (!array_key_exists($shortName = (new \ReflectionClass($executable))->getShortName(), $this->mapping))
{
throw new \RuntimeException(
sprintf(
'Mapping not found for "%s", did you forget to add the relevant dispatcher strategy in %s?',
$shortName, __CLASS__
)
);
}
// oh shit, queue executable dispatcher requires different ctor dependencies than Process... reflection
// (auryn) is one solution
return new $this->mapping[$shortName];
}
}
// ---- different ways of dispatching
interface DispatchStrategy
{
/**
* @param Executable $executable
* @param string $payload
*
* @return mixed // haven't decided yet shit
*/
public function dispatch(Executable $executable, string $payload);
}
class QueueExecutableDispatcher extends DispatchStrategy
{
/**
* @var AmqpContext
*/
private $context;
/**
* ExecutableDispatcher constructor.
*
* @param AmqpContext $context
*/
public function __construct(AmqpContext $context)
{
$this->context = $context;
}
/**
* @inheritdoc
*/
public function dispatch(Executable $executable, string $payload)
{
// sanity check
if ($executable instanceof QueueExecutable)
{
$queue = $this->context->createQueue($executable->getQueueName());
$message = $this->context->createMessage($payload);
$this->context->declareQueue($queue);
$this->context->createProducer()->send($queue, $message);
}
}
}
class ProcessExecutableDispatcher extends DispatchStrategy
{
// Here we dispatch to a process instead
}
// QueueExecutable is a class the user will implement that has the method getQueueName(). Extends Executable interface (nothing in there atm)
// ProcessExecutable is another class the user will implement, that may have other methods. Also extends executable interface. Nothing in this interface.