[sales] Make storage available again when offer expires

This commit is contained in:
Mark Spanbroek 2022-03-31 15:08:26 +02:00 committed by markspanbroek
parent 55e326b467
commit befebcf325
2 changed files with 28 additions and 5 deletions

View File

@ -29,6 +29,7 @@ type
offer: ?StorageOffer offer: ?StorageOffer
subscription: ?Subscription subscription: ?Subscription
waiting: ?Future[void] waiting: ?Future[void]
finished: bool
OnSale = proc(offer: StorageOffer) {.gcsafe, upraises: [].} OnSale = proc(offer: StorageOffer) {.gcsafe, upraises: [].}
func new*(_: type Sales, market: Market): Sales = func new*(_: type Sales, market: Market): Sales =
@ -69,17 +70,30 @@ proc sendOffer(negotiation: Negotiation) {.async.} =
let offer = negotiation.createOffer() let offer = negotiation.createOffer()
negotiation.offer = some await negotiation.sales.market.offerStorage(offer) negotiation.offer = some await negotiation.sales.market.offerStorage(offer)
proc onSelect(negotiation: Negotiation, offerId: array[32, byte]) = proc finish(negotiation: Negotiation, success: bool) =
if negotiation.finished:
return
negotiation.finished = true
if subscription =? negotiation.subscription: if subscription =? negotiation.subscription:
asyncSpawn subscription.unsubscribe() asyncSpawn subscription.unsubscribe()
without offer =? negotiation.offer:
return if waiting =? negotiation.waiting:
if offer.id == offerId: waiting.cancel()
if success and offer =? negotiation.offer:
if onSale =? negotiation.sales.onSale: if onSale =? negotiation.sales.onSale:
onSale(offer) onSale(offer)
else: else:
negotiation.sales.add(negotiation.availability) negotiation.sales.add(negotiation.availability)
proc onSelect(negotiation: Negotiation, offerId: array[32, byte]) =
if offer =? negotiation.offer and offer.id == offerId:
negotiation.finish(success = true)
else:
negotiation.finish(success = false)
proc subscribeSelect(negotiation: Negotiation) {.async.} = proc subscribeSelect(negotiation: Negotiation) {.async.} =
without offer =? negotiation.offer: without offer =? negotiation.offer:
return return
@ -93,6 +107,7 @@ proc waitForExpiry(negotiation: Negotiation) {.async.} =
without offer =? negotiation.offer: without offer =? negotiation.offer:
return return
await negotiation.sales.market.waitUntil(offer.expiry) await negotiation.sales.market.waitUntil(offer.expiry)
negotiation.finish(success = false)
proc start(negotiation: Negotiation) {.async.} = proc start(negotiation: Negotiation) {.async.} =
let sales = negotiation.sales let sales = negotiation.sales
@ -100,7 +115,7 @@ proc start(negotiation: Negotiation) {.async.} =
sales.remove(availability) sales.remove(availability)
await negotiation.sendOffer() await negotiation.sendOffer()
await negotiation.subscribeSelect() await negotiation.subscribeSelect()
await negotiation.waitForExpiry() negotiation.waiting = some negotiation.waitForExpiry()
proc handleRequest(sales: Sales, request: StorageRequest) {.async.} = proc handleRequest(sales: Sales, request: StorageRequest) {.async.} =
without availability =? sales.findAvailability(request): without availability =? sales.findAvailability(request):

View File

@ -95,3 +95,11 @@ suite "Sales":
otherOffer = await market.offerStorage(otherOffer) otherOffer = await market.offerStorage(otherOffer)
await market.selectOffer(otherOffer.id) await market.selectOffer(otherOffer.id)
check sales.available.contains(availability) check sales.available.contains(availability)
test "makes storage available again when offer expires":
sales.add(availability)
discard await market.requestStorage(request)
let offer = market.offered[0]
market.advanceTimeTo(offer.expiry)
await sleepAsync(chronos.seconds(1))
check sales.available.contains(availability)