Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Some minor performance & readability enhancements #53596

Merged
merged 1 commit into from
Nov 21, 2024

Conversation

dshafik
Copy link
Contributor

@dshafik dshafik commented Nov 20, 2024

During my latest Inside Laravel livestream I noticed some minor inefficiencies in the Dispatcher code. These most likely are just older code that never got updated.

This includes 3 changes:

  1. Useisset($uses[InteractsWithQueue::class], $uses[Queueable::class]) instead of a two expensive in_array() calls, this takes two O(n) operations to just O(1).
  2. It replaces an expensive call_user_func() call with a dynamic method call, using ($this->queueResolver) to dererefence the property before calling the closure within.
  3. Simplifies the pushCommandToQueue() implementation which previously checked if queue and/or delay were set and then calling pushOn() or laterOn() when with named params we can easily just call push() and later() — the use of queue: $command->queue ?? null rather than just queue: $command->queue is for readability. This one is the only one I'm concerned about, it's possible that an implementation of the Queue interface/child of the Queue abstract class has different behavior than just wrapping push() and later() — but as those must support the queue param I don't see any issue with it.

@milwad-dev
Copy link
Contributor

The refactored version is harder to read than the previous version! (For me)

@Diddyy
Copy link

Diddyy commented Nov 20, 2024

In contrast, I like it and can follow it better. I think it helps keep a clean code base so +1!

@crynobone crynobone marked this pull request as draft November 20, 2024 14:24
@crynobone
Copy link
Member

Marking as draft since tests are failing.

@dshafik dshafik force-pushed the dispatcher-optimizations branch from f17d980 to 7377c4b Compare November 20, 2024 18:22
@dshafik
Copy link
Contributor Author

dshafik commented Nov 20, 2024

@crynobone all tests are passing now, only one minor change to a single test (mocking laterOn which is no longer called instead of later)

@dshafik dshafik marked this pull request as ready for review November 20, 2024 18:26
if (in_array(InteractsWithQueue::class, $uses) &&
in_array(Queueable::class, $uses) &&
! $command->job) {
if (isset($uses[InteractsWithQueue::class], $uses[Queueable::class]) && ! $command->job) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an incorrect refactor. isset looks at the keys. in_array looks at the values.

Copy link
Contributor

@ralphjsmit ralphjsmit Nov 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't class_uses_recursive() outputting the exact same key as value?

[
   SomeConcern::class => SomeConcern::class,
]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GrahamCampbell as @ralphjsmit points out, the result of class_uses_recursive() is a key-value pair with the trait name for both, therefore you can use isset() to check for the usage of a trait (O(1)) rather than traverse the array till you find the value using in_array(). (O(n))

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be fine and we use isset() as well for

$uses = array_flip(class_uses_recursive(static::class));
if (isset($uses[RefreshDatabase::class])) {
$this->refreshDatabase();
}
if (isset($uses[DatabaseMigrations::class])) {
$this->runDatabaseMigrations();
}
if (isset($uses[DatabaseTruncation::class])) {
$this->truncateDatabaseTables();
}
if (isset($uses[DatabaseTransactions::class])) {
$this->beginDatabaseTransaction();
}
if (isset($uses[WithoutMiddleware::class])) {
$this->disableMiddlewareForAllTests();
}
if (isset($uses[WithFaker::class])) {
$this->setUpFaker();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@crynobone the array_flip() in that example should probably be removed too… (unrelated to this PR)

if (isset($command->delay)) {
return $queue->later($command->delay, $command);
return $queue->later($command->delay, $command, queue: $command->queue ?? null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it not possible to maintain using laterOn and pushOn for 11.x and change it for 12.x?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@crynobone The methods aren't going anywhere, it's just unclear if there is any implementation that does anything except wrap the other functions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, just thinking if existing application using Bus::spy() and Bus::shouldHaveReceived('laterOn') and with these changes, it starts to cause failing tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to back that part out, although those feel like brittle tests I don't think it's good to break things for the sake of breaking things.

@taylorotwell taylorotwell merged commit 9cfae0a into laravel:11.x Nov 21, 2024
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants