Complex classes like PredisAdapter often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use PredisAdapter, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 16 | class PredisAdapter implements QueueAdapterInterface, SchedulerAdapterInterface |
||
| 17 | { |
||
| 18 | |||
| 19 | private $client; |
||
| 20 | |||
| 21 | public function __construct(Client $client) |
||
| 25 | |||
| 26 | public function queueCommand(string $queueName, string $id, string $serialized) |
||
| 36 | |||
| 37 | public function awaitCommand(string $queueName, int $timeout = null): ReceivedCommand |
||
| 63 | |||
| 64 | public function getCommandStatus(string $queueName, string $id): string |
||
| 68 | |||
| 69 | public function setCommandCompleted(string $queueName, string $id) |
||
| 75 | |||
| 76 | public function setCommandFailed(string $queueName, string $id) |
||
| 82 | |||
| 83 | public function putQueue(string $queueName) |
||
| 89 | |||
| 90 | public function getQueueNames(): array |
||
| 94 | |||
| 95 | public function getQueuedCount(string $queueName): int |
||
| 99 | |||
| 100 | public function getQueuedIds(string $queueName, int $offset = 0, int $limit = 10): array |
||
| 104 | |||
| 105 | public function getConsumingCount(string $queueName): int |
||
| 109 | |||
| 110 | public function getConsumingIds(string $queueName, int $offset = 0, int $limit = 10): array |
||
| 114 | |||
| 115 | public function readCommand(string $queueName, string $id): string |
||
| 123 | |||
| 124 | public function clearQueue(string $queueName) |
||
| 125 | { |
||
| 126 | self::cEmptyQueue($this->client, $queueName); |
||
| 127 | } |
||
| 128 | |||
| 129 | public function deleteQueue(string $queueName) |
||
| 130 | { |
||
| 131 | $this->client->pipeline(function (ClientContextInterface $client) use ($queueName) { |
||
| 132 | self::cDeleteQueue($client, $queueName); |
||
| 133 | }); |
||
| 134 | $this->clearSchedule([$queueName]); |
||
| 135 | } |
||
| 136 | |||
| 137 | public function purgeCommand(string $queueName, string $id) |
||
| 138 | { |
||
| 139 | $this->client->pipeline(function (ClientContextInterface $client) use ($queueName, $id) { |
||
| 140 | $client->hdel(":{$queueName}:command_store", [ $id ]); |
||
| 141 | $client->hdel(":{$queueName}:command_status", [ $id ]); |
||
| 142 | self::cReleaseReservedCommandIds($client, $queueName, [ $id ]); |
||
| 143 | $json = json_encode([ $queueName, $id ]); |
||
| 144 | $client->lrem(":{$queueName}:queue", 1, $id); |
||
| 145 | $client->lrem(":{$queueName}:consuming", 1, $id); |
||
| 146 | $client->zrem(':schedule', $json); |
||
| 147 | }); |
||
| 148 | } |
||
| 149 | |||
| 150 | public function scheduleCommand(string $queueName, string $id, string $serialized, \DateTime $dateTime) |
||
| 151 | { |
||
| 152 | if (!$this->storeCommandAndCheckIfIdReserved($queueName, $id, $serialized)) { |
||
| 153 | $this->client->pipeline( |
||
| 154 | function (ClientContextInterface $client) use ($queueName, $id, $dateTime) { |
||
| 155 | self::cReserveCommandId($client, $queueName, $id); |
||
| 156 | self::cUpdateCommandStatus($client, $queueName, $id, self::STATUS_SCHEDULED); |
||
| 157 | $json = json_encode([ $queueName, $id ]); |
||
| 158 | $client->zadd(':schedule', [ $json => $dateTime->getTimestamp() ]); |
||
| 159 | } |
||
| 160 | ); |
||
| 161 | } |
||
| 162 | } |
||
| 163 | |||
| 164 | public function cancelScheduledCommand(string $queueName, string $id) |
||
| 165 | { |
||
| 166 | $this->purgeCommand($queueName, $id); |
||
| 167 | } |
||
| 168 | |||
| 169 | public function clearSchedule(array $queueNames = null, \DateTime $start = null, \DateTime $end = null) |
||
| 170 | { |
||
| 171 | $result = $this->client->zrangebyscore( |
||
| 172 | ':schedule', |
||
| 173 | $start ? $start->getTimestamp() : '-inf', |
||
| 174 | $end ? $end->getTimestamp() : '+inf' |
||
| 175 | ); |
||
| 176 | if (!empty($result)) { |
||
| 177 | $this->client->pipeline(function (ClientContextInterface $client) use ($result, $queueNames) { |
||
| 178 | $idsByQueue = [ ]; |
||
| 179 | foreach ($result as $json) { |
||
| 180 | list($thisQueueName, $id) = json_decode($json, true); |
||
| 181 | if ($queueNames === null || in_array($thisQueueName, $queueNames, true)) { |
||
| 182 | $client->zrem(':schedule', [ $json ]); |
||
| 183 | $idsByQueue[ $thisQueueName ][ ] = $id; |
||
| 184 | } |
||
| 185 | } |
||
| 186 | foreach ($idsByQueue as $queueName => $ids) { |
||
| 187 | self::cReleaseReservedCommandIds($client, $queueName, $ids); |
||
| 188 | } |
||
| 189 | }); |
||
| 190 | } |
||
| 191 | } |
||
| 192 | |||
| 193 | public function receiveDueCommands( |
||
| 238 | |||
| 239 | private function storeCommandAndCheckIfIdReserved(string $queueName, string $id, string $serialized): bool |
||
| 250 | |||
| 251 | private static function cRetrieveCommand($client, string $queueName, string $id) |
||
| 255 | |||
| 256 | private static function cReserveCommandId($client, string $queueName, string $id) |
||
| 260 | |||
| 261 | private static function cEndCommand($client, string $queueName, string $id, string $status) |
||
| 268 | |||
| 269 | private static function cReleaseReservedCommandIds($client, string $queueName, array $ids) |
||
| 273 | |||
| 274 | private static function cUpdateCommandStatus($client, string $queueName, string $id, string $status) |
||
| 278 | |||
| 279 | private static function cAddQueue($client, string $queueName) |
||
| 283 | |||
| 284 | private static function cEmptyQueue($client, string $queueName) |
||
| 285 | { |
||
| 286 | $client->del([ |
||
| 287 | ":{$queueName}:queue", |
||
| 288 | ":{$queueName}:consuming", |
||
| 289 | ":{$queueName}:command_status", |
||
| 293 | |||
| 294 | private static function cDeleteQueue($client, string $queueName) |
||
| 299 | } |
||
| 300 |