Skip to content

Commit d8e9adb

Browse files
committed
chore(agent): ensure transaction is always stopped when laravel horizon is used
1 parent f049a15 commit d8e9adb

File tree

3 files changed

+90
-29
lines changed

3 files changed

+90
-29
lines changed

agent/fw_laravel.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,21 @@ static nr_status_t nr_laravel_should_assign_generic_path(const nrtxn_t* txn,
11931193
return NR_FAILURE;
11941194
}
11951195

1196+
/*
1197+
* Ensure that the transaction is properly stopped when Laravel Horizon is being
1198+
* used by wrapping the handle method of the HorizonCommand and
1199+
* SupervisorCommand class.
1200+
*/
1201+
NR_PHP_WRAPPER(nr_laravel_horizon_end_txn) {
1202+
NR_UNUSED_SPECIALFN;
1203+
(void)wraprec;
1204+
1205+
nr_php_txn_end(1, 0 TSRMLS_CC);
1206+
1207+
nrl_verbosedebug(NRL_TXN, "Ending Laravel Horizon Transaction");
1208+
}
1209+
NR_PHP_WRAPPER_END
1210+
11961211
void nr_laravel_enable(TSRMLS_D) {
11971212
/*
11981213
* We set the path to 'unknown' to prevent having to name routing errors.
@@ -1231,6 +1246,19 @@ void nr_laravel_enable(TSRMLS_D) {
12311246
nr_php_wrap_user_function_before_after_clean(
12321247
NR_PSTR("Symfony\\Component\\Console\\Application::doRun"),
12331248
nr_laravel_console_application_dorun, NULL, NULL);
1249+
1250+
/*
1251+
* The following functions have been added to ensure that the transaction
1252+
* is properly stopped when Laravel Horizon is being used. This is
1253+
* accomplished by wrapping the handle method of the HorizonCommand class and
1254+
* the SupervisorCommand class.
1255+
*/
1256+
nr_php_wrap_user_function_before_after_clean(
1257+
NR_PSTR("Laravel\\Horizon\\Console\\HorizonCommand::handle"),
1258+
nr_laravel_horizon_end_txn, NULL, NULL);
1259+
nr_php_wrap_user_function_before_after_clean(
1260+
NR_PSTR("Laravel\\Horizon\\Console\\SupervisorCommand::handle"),
1261+
nr_laravel_horizon_end_txn, NULL, NULL);
12341262
#else
12351263
nr_php_wrap_user_function(NR_PSTR("Symfony\\Component\\Console\\Application::doRun"),
12361264
nr_laravel_console_application_dorun TSRMLS_CC);

agent/fw_laravel_queue.c

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -839,21 +839,6 @@ NR_PHP_WRAPPER(nr_laravel_queue_queue_createpayload) {
839839
}
840840
NR_PHP_WRAPPER_END
841841

842-
/*
843-
* Ensure that the transaction is properly stopped when Laravel Horizon is being
844-
* used by wrapping the handle method of the HorizonCommand and
845-
* SupervisorCommand class.
846-
*/
847-
NR_PHP_WRAPPER(nr_laravel_horizon_end_txn) {
848-
NR_UNUSED_SPECIALFN;
849-
(void)wraprec;
850-
851-
nr_php_txn_end(1, 0 TSRMLS_CC);
852-
853-
nrl_verbosedebug(NRL_TXN, "Ending Laravel Horizon Transaction");
854-
}
855-
NR_PHP_WRAPPER_END
856-
857842
void nr_laravel_queue_enable(TSRMLS_D) {
858843
/*
859844
* Hook the command class that implements Laravel's queue:work command so
@@ -886,20 +871,6 @@ void nr_laravel_queue_enable(TSRMLS_D) {
886871
nr_php_wrap_user_function_before_after_clean(
887872
NR_PSTR("Illuminate\\Queue\\SyncQueue::raiseAfterJobEvent"),
888873
nr_laravel_queue_worker_raiseAfterJobEvent_before, NULL, NULL);
889-
890-
/*
891-
* The following functions have been added to ensure that the transaction
892-
* is properly stopped when Laravel Horizon is being used. This is
893-
* accomplished by wrapping the handle method of the HorizonCommand class and
894-
* the SupervisorCommand class.
895-
*/
896-
nr_php_wrap_user_function_before_after_clean(
897-
NR_PSTR("Laravel\\Horizon\\Console\\HorizonCommand::handle"),
898-
nr_laravel_horizon_end_txn, NULL, NULL);
899-
nr_php_wrap_user_function_before_after_clean(
900-
NR_PSTR("Laravel\\Horizon\\Console\\SupervisorCommand::handle"),
901-
nr_laravel_horizon_end_txn, NULL, NULL);
902-
903874
#else
904875

905876
/*
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/*
3+
* Copyright 2020 New Relic Corporation. All rights reserved.
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*DESCRIPTION
8+
This test ensures that when the newrelic.special = disable_laravel_queue INI setting
9+
is set, the transaction is still properly stopped when HorizonCommand::handle is executed.
10+
This test verifies this behavior by first making sure the transaction exists and the
11+
transaction trace is not empty. Then it calls the HorizonCommand::handle method and
12+
verifies that the transaction has been stopped by checking that there was no harvest received.
13+
*/
14+
15+
/*SKIPIF
16+
<?php
17+
if (version_compare(PHP_VERSION, "8.0", "<")) {
18+
die("skip: PHP < 8.0 not supported\n");
19+
}
20+
*/
21+
22+
/*INI
23+
newrelic.framework = laravel
24+
newrelic.special = disable_laravel_queue
25+
*/
26+
27+
/*EXPECT_HARVEST
28+
no
29+
*/
30+
31+
/*EXPECT
32+
foobar
33+
Custom/foobar
34+
handle function
35+
foobar
36+
*/
37+
38+
require_once(__DIR__ . '/mock_horizon_happy_path.php');
39+
require_once(__DIR__.'/../../../include/integration.php');
40+
41+
use Laravel\Horizon\Console\HorizonCommand;
42+
use NewRelic\Integration\Transaction;
43+
44+
function foobar() {
45+
echo "foobar\n";
46+
}
47+
function get_txn() {
48+
return new Transaction;
49+
}
50+
51+
newrelic_add_custom_tracer('foobar');
52+
foobar();
53+
54+
$txn = get_txn();
55+
foreach ($txn->getTrace()->findSegmentsByName('Custom/foobar') as $segment) {
56+
echo $segment->name;
57+
echo "\n";
58+
}
59+
60+
$horizon = new HorizonCommand();
61+
$horizon->handle();
62+
foobar();

0 commit comments

Comments
 (0)