Connection.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. namespace Illuminate\Redis\Connections;
  3. use Closure;
  4. use Illuminate\Contracts\Events\Dispatcher;
  5. use Illuminate\Redis\Events\CommandExecuted;
  6. use Illuminate\Redis\Events\CommandFailed;
  7. use Illuminate\Redis\Limiters\ConcurrencyLimiterBuilder;
  8. use Illuminate\Redis\Limiters\DurationLimiterBuilder;
  9. use Illuminate\Support\Traits\Macroable;
  10. use Throwable;
  11. /**
  12. * @mixin \Redis
  13. */
  14. abstract class Connection
  15. {
  16. use Macroable {
  17. __call as macroCall;
  18. }
  19. /**
  20. * The Redis client.
  21. *
  22. * @var \Redis
  23. */
  24. protected $client;
  25. /**
  26. * The Redis connection name.
  27. *
  28. * @var string|null
  29. */
  30. protected $name;
  31. /**
  32. * The event dispatcher instance.
  33. *
  34. * @var \Illuminate\Contracts\Events\Dispatcher|null
  35. */
  36. protected $events;
  37. /**
  38. * Subscribe to a set of given channels for messages.
  39. *
  40. * @param array|string $channels
  41. * @param \Closure $callback
  42. * @param string $method
  43. * @return void
  44. */
  45. abstract public function createSubscription($channels, Closure $callback, $method = 'subscribe');
  46. /**
  47. * Funnel a callback for a maximum number of simultaneous executions.
  48. *
  49. * @param string $name
  50. * @return \Illuminate\Redis\Limiters\ConcurrencyLimiterBuilder
  51. */
  52. public function funnel($name)
  53. {
  54. return new ConcurrencyLimiterBuilder($this, $name);
  55. }
  56. /**
  57. * Throttle a callback for a maximum number of executions over a given duration.
  58. *
  59. * @param string $name
  60. * @return \Illuminate\Redis\Limiters\DurationLimiterBuilder
  61. */
  62. public function throttle($name)
  63. {
  64. return new DurationLimiterBuilder($this, $name);
  65. }
  66. /**
  67. * Get the underlying Redis client.
  68. *
  69. * @return mixed
  70. */
  71. public function client()
  72. {
  73. return $this->client;
  74. }
  75. /**
  76. * Subscribe to a set of given channels for messages.
  77. *
  78. * @param array|string $channels
  79. * @param \Closure $callback
  80. * @return void
  81. */
  82. public function subscribe($channels, Closure $callback)
  83. {
  84. $this->createSubscription($channels, $callback, __FUNCTION__);
  85. }
  86. /**
  87. * Subscribe to a set of given channels with wildcards.
  88. *
  89. * @param array|string $channels
  90. * @param \Closure $callback
  91. * @return void
  92. */
  93. public function psubscribe($channels, Closure $callback)
  94. {
  95. $this->createSubscription($channels, $callback, __FUNCTION__);
  96. }
  97. /**
  98. * Run a command against the Redis database.
  99. *
  100. * @param string $method
  101. * @param array $parameters
  102. * @return mixed
  103. */
  104. public function command($method, array $parameters = [])
  105. {
  106. $start = microtime(true);
  107. try {
  108. $result = $this->client->{$method}(...$parameters);
  109. } catch (Throwable $e) {
  110. $this->events?->dispatch(new CommandFailed(
  111. $method, $this->parseParametersForEvent($parameters), $e, $this
  112. ));
  113. throw $e;
  114. }
  115. $time = round((microtime(true) - $start) * 1000, 2);
  116. $this->events?->dispatch(new CommandExecuted(
  117. $method, $this->parseParametersForEvent($parameters), $time, $this
  118. ));
  119. return $result;
  120. }
  121. /**
  122. * Parse the command's parameters for event dispatching.
  123. *
  124. * @param array $parameters
  125. * @return array
  126. */
  127. protected function parseParametersForEvent(array $parameters)
  128. {
  129. return $parameters;
  130. }
  131. /**
  132. * Fire the given event if possible.
  133. *
  134. * @param mixed $event
  135. * @return void
  136. *
  137. * @deprecated since Laravel 11.x
  138. */
  139. protected function event($event)
  140. {
  141. $this->events?->dispatch($event);
  142. }
  143. /**
  144. * Register a Redis command listener with the connection.
  145. *
  146. * @param \Closure $callback
  147. * @return void
  148. */
  149. public function listen(Closure $callback)
  150. {
  151. $this->events?->listen(CommandExecuted::class, $callback);
  152. }
  153. /**
  154. * Register a Redis command failure listener with the connection.
  155. *
  156. * @param \Closure $callback
  157. * @return void
  158. */
  159. public function listenForFailures(Closure $callback)
  160. {
  161. $this->events?->listen(CommandFailed::class, $callback);
  162. }
  163. /**
  164. * Get the connection name.
  165. *
  166. * @return string|null
  167. */
  168. public function getName()
  169. {
  170. return $this->name;
  171. }
  172. /**
  173. * Set the connection's name.
  174. *
  175. * @param string $name
  176. * @return $this
  177. */
  178. public function setName($name)
  179. {
  180. $this->name = $name;
  181. return $this;
  182. }
  183. /**
  184. * Get the event dispatcher used by the connection.
  185. *
  186. * @return \Illuminate\Contracts\Events\Dispatcher|null
  187. */
  188. public function getEventDispatcher()
  189. {
  190. return $this->events;
  191. }
  192. /**
  193. * Set the event dispatcher instance on the connection.
  194. *
  195. * @param \Illuminate\Contracts\Events\Dispatcher $events
  196. * @return void
  197. */
  198. public function setEventDispatcher(Dispatcher $events)
  199. {
  200. $this->events = $events;
  201. }
  202. /**
  203. * Unset the event dispatcher instance on the connection.
  204. *
  205. * @return void
  206. */
  207. public function unsetEventDispatcher()
  208. {
  209. $this->events = null;
  210. }
  211. /**
  212. * Pass other method calls down to the underlying client.
  213. *
  214. * @param string $method
  215. * @param array $parameters
  216. * @return mixed
  217. */
  218. public function __call($method, $parameters)
  219. {
  220. if (static::hasMacro($method)) {
  221. return $this->macroCall($method, $parameters);
  222. }
  223. return $this->command($method, $parameters);
  224. }
  225. }