Skip to content

Commit 6f80c4c

Browse files
authored
fix: Session transaction queue fix (#832)
* fix: Session transaction queue pop relocated to earlier occurrence in request * chore: Linter and PHPStan compliance met
1 parent ffd1430 commit 6f80c4c

File tree

3 files changed

+31
-17
lines changed

3 files changed

+31
-17
lines changed

includes/utils/class-ql-session-handler.php

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ public function init() {
107107
*/
108108
add_action( 'woocommerce_set_cart_cookies', [ $this, 'set_customer_session_token' ], 10 );
109109
add_action( 'woographql_update_session', [ $this, 'set_customer_session_token' ], 10 );
110-
add_action( 'graphql_after_resolve_field', [ $this, 'save_if_dirty' ], 10, 4 );
111110
add_action( 'shutdown', [ $this, 'save_data' ] );
112111
add_action( 'wp_logout', [ $this, 'destroy_session' ] );
113112

@@ -413,19 +412,9 @@ public function forget_session() {
413412
/**
414413
* Save any changes to database after a session mutations has been run.
415414
*
416-
* @param mixed $source Operation root object.
417-
* @param array $args Operation arguments.
418-
* @param \WPGraphQL\AppContext $context AppContext instance.
419-
* @param \GraphQL\Type\Definition\ResolveInfo $info Operation ResolveInfo object.
420-
*
421415
* @return void
422416
*/
423-
public function save_if_dirty( $source, $args, $context, $info ) {
424-
// Bail early, if not one of the session mutations.
425-
if ( ! in_array( $info->fieldName, Session_Transaction_Manager::get_session_mutations(), true ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
426-
return;
427-
}
428-
417+
public function save_if_dirty() {
429418
// Update if user recently authenticated.
430419
if ( is_user_logged_in() && get_current_user_id() !== $this->_customer_id ) {
431420
$this->_customer_id = get_current_user_id();

includes/utils/class-session-transaction-manager.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ public function __construct( &$session_handler ) {
6060
$this->session_handler = $session_handler;
6161

6262
add_action( 'graphql_before_resolve_field', [ $this, 'update_transaction_queue' ], 10, 4 );
63-
add_action( 'graphql_process_http_request_response', [ $this, 'pop_transaction_id' ], 20 );
63+
add_action( 'graphql_mutation_response', [ $this, 'pop_transaction_id' ], 20, 6 );
64+
add_action( 'woographql_session_transaction_complete', [ $this->session_handler, 'save_if_dirty' ], 10 );
6465
}
6566

6667
/**
@@ -202,16 +203,28 @@ public function get_transaction_queue() {
202203
/**
203204
* Pop transaction ID off the top of the queue, ending the transaction.
204205
*
206+
* @param array $payload The Payload returned from the mutation.
207+
* @param array $input The mutation input args, after being filtered by 'graphql_mutation_input'.
208+
* @param array $unfiltered_input The unfiltered input args of the mutation
209+
* @param \WPGraphQL\AppContext $context The AppContext object.
210+
* @param \GraphQL\Type\Definition\ResolveInfo $info The ResolveInfo object.
211+
* @param string $mutation The name of the mutation field.
212+
*
205213
* @throws \GraphQL\Error\UserError If transaction ID is not on the top of the queue.
206214
*
207215
* @return void
208216
*/
209-
public function pop_transaction_id() {
217+
public function pop_transaction_id( $payload, $input, $unfiltered_input, $context, $info, $mutation ) {
210218
// Bail if transaction not started.
211219
if ( is_null( $this->transaction_id ) ) {
212220
return;
213221
}
214222

223+
// Bail if not the expected mutation.
224+
if ( str_starts_with( $this->transaction_id, "wooSession_{$mutation}_" ) ) {
225+
return;
226+
}
227+
215228
// Get transaction queue.
216229
$transaction_queue = get_transient( "woo_session_transactions_queue_{$this->session_handler->get_customer_id()}" );
217230

@@ -223,6 +236,16 @@ public function pop_transaction_id() {
223236
// Remove Transaction ID and update queue.
224237
array_shift( $transaction_queue );
225238
$this->save_transaction_queue( $transaction_queue );
239+
240+
/**
241+
* Mark transaction completion
242+
*
243+
* @param string|null $transition_id Removed transaction ID.
244+
* @param array $transaction_queue Transaction Queue.
245+
*/
246+
do_action( 'woographql_session_transaction_complete', $this->transaction_id, $transaction_queue );
247+
248+
// Clear transaction ID.
226249
$this->transaction_id = null;
227250
}
228251
}

tests/functional/CartTransactionQueueCest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,11 @@ public function testCartTransactionQueueWithConcurrentRequest( FunctionalTester
268268
$client = new \GuzzleHttp\Client( compact( 'base_uri', 'headers', 'timeout' ) );
269269

270270
$iterator = static function ( $requests ) use ( $client ) {
271-
$stagger = 1000;
271+
$stagger = 800;
272272
foreach ( $requests as $index => $payload ) {
273273
yield static function () use ( $client, $stagger, $index, $payload ) {
274274
$body = json_encode( $payload );
275-
$delay = $stagger * $index + 1;
275+
$delay = $stagger * ($index + 1);
276276
$connected = false;
277277
$progress = static function ( $downloadTotal, $downloadedBytes, $uploadTotal, $uploadedBytes ) use ( $index, &$connected ) {
278278
if ( $uploadTotal === $uploadedBytes && 0 === $downloadTotal && ! $connected ) {
@@ -294,8 +294,10 @@ public function testCartTransactionQueueWithConcurrentRequest( FunctionalTester
294294
\codecept_debug( "Finished session mutation request $index @ " . ( new \Carbon\Carbon() )->format( 'Y-m-d H:i:s' ) );
295295

296296
$expected = $expected_responses[ $index ];
297+
$headers = $response->getHeaders();
297298
$body = json_decode( $response->getBody(), true );
298-
299+
300+
\codecept_debug( $headers );
299301
\codecept_debug( $body );
300302
$I->assertEquals( $expected, $body['data'] );
301303
},

0 commit comments

Comments
 (0)