Skip to content

Instantly share code, notes, and snippets.

@mikedfunk
Last active January 18, 2019 21:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikedfunk/2ba4bb1238e3d6a99e8d31746b2ed20e to your computer and use it in GitHub Desktop.
Save mikedfunk/2ba4bb1238e3d6a99e8d31746b2ed20e to your computer and use it in GitHub Desktop.
<?php declare(strict_types=1);
namespace MyApp\Adapter\Repository\Couchbase;
use CouchbaseException;
use MyApp\Exception\DocumentIsLockedException;
class CartRepository
{
// ...
/**
* Further down this could throw a
* \MyApp\Exception\DocumentIsLockedException if the document stays
* locked for too long. Be sure to catch that above!
*/
public function getCartOfId(
$cartId,
bool $isLockNeeded = true
): Cart? {
// if no document exists, no need to wait for lock, acquire lock, etc.
if (!$this->documentOfIdExists($cartId)) {
return false;
}
if ($isLockNeeded) {
$jsonCart = $this->lockAndGetCouchbaseData($cartId);
return $this->jsonSerializer->
deserialize($jsonCart, Cart::class, 'json');
}
$jsonCart = $this->couchbaseCluster->
openBucket(self::CART_BUCKET_NAME)->
get($cartId)->
value;
$jsonCart = $this->transformations->apply($jsonCart);
return $this->jsonSerializer->
deserialize($jsonCart, Cart::class, 'json');
}
/**
* @throws \UnexpectedValueException
* @throws \CouchbaseException
*
* @param bool $dangerouslySkipLocking For scripts we do not want to wait
* for lock to be released, acquire a lock, or unlock when performing a
* destructive action.
*/
public function storeCart(
Cart $cart,
bool $dangerouslySkipLocking = false
): void {
$cartId = $cart->getId();
$jsonContent = $this->jsonSerializer->serialize($cart, 'json');
$bucket = $this->couchbaseCluster->
openBucket(self::CART_BUCKET_NAME);
// no need to deal with locks in these cases
if (!$this->documentOfIdExists($cartId)) {
$bucket->upsert($cartId, $jsonContent);
return;
}
$cartWasLockedDuringCurrentProcess = $this->lockHandler->
wasLockedDuringCurrentProcess($cartId);
$unlockOptions = $this->
getCouchbaseUnlockOptionsForStore(
$cartId,
$cartWasLockedDuringCurrentProcess,
$dangerouslySkipLocking
);
try {
$bucket->replace($cartId, $jsonContent, $unlockOptions);
} catch (CouchbaseException $exception) {
if($exception->getCode() == COUCHBASE_KEY_EEXISTS) {
$msg = "Can't persist cart of doc id: {$cartId}." .
" Reason: invalid unlock id provided.";
throw new \UnexpectedValueException($msg);
}
throw $exception;
}
// release cart lock if acquired in this process
if ($cartWasLockedDuringCurrentProcess) {
$this->lockHandler->markAsReleased($cartId);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment