Database Reference
In-Depth Information
The actual code, then, looks something like the following:
def
def
expire_carts
(
timeout
):
now
=
datetime
.
utcnow
()
threshold
=
now
-
timedelta
(
seconds
=
timeout
)
# Lock and find all the expiring carts
db
.
cart
.
update
(
{
'status'
:
'active'
,
'last_modified'
: {
'$lt'
:
threshold
} },
{
'$set'
: {
'status'
:
'expiring'
} },
multi
=
True
)
# Actually expire each cart
for
for
cart
iin
db
.
cart
.
find
({
'status'
:
'expiring'
}):
# Return all line items to inventory
for
for
item
iin
cart
[
'items'
]:
db
.
product
.
update
(
{
'_id'
:
item
[
'sku'
],
'carted.cart_id'
:
cart
[
'id'
] },
{
'$inc'
: {
'qty'
:
item
[
'qty'
] },
'$pull'
: {
'carted'
: {
'cart_id'
:
cart
[
'id'
] } } })
<
db
.
cart
.
update
(
{
'_id'
:
cart
[
'id'
] },
{
'$set'
: {
status
': '
expired
' })
We're using
multi=True
to “batch up” our cart expiration initial lock.
Un
fortunately, we need to handle expiring the carts individually, so this function
can actually be somewhat time-consuming. Note, however, that the
expire_carts
function is safely resumable, since we have effectively “locked” the carts needing
expiration by placing them in
"expiring"
status.
we're expiring. Note that without the
carted
property, our function would become
unsafe to retry if an exception occurred since the inventory could be incremented
multiple times for a single cart.
keep it around any more.