[sales] call onSale() when offer has been selected
This commit is contained in:
parent
71baedb5ec
commit
2ffde32772
|
@ -46,5 +46,5 @@ method subscribeSelection*(market: Market,
|
||||||
Future[Subscription] {.base, async.} =
|
Future[Subscription] {.base, async.} =
|
||||||
raiseAssert("not implemented")
|
raiseAssert("not implemented")
|
||||||
|
|
||||||
method unsubscribe*(subscription: Subscription) {.base, async.} =
|
method unsubscribe*(subscription: Subscription) {.base, async, upraises:[].} =
|
||||||
raiseAssert("not implemented")
|
raiseAssert("not implemented")
|
||||||
|
|
|
@ -13,14 +13,16 @@ const DefaultOfferExpiryInterval = (10 * 60).u256
|
||||||
type
|
type
|
||||||
Sales* = ref object
|
Sales* = ref object
|
||||||
market: Market
|
market: Market
|
||||||
available*: seq[Availability]
|
|
||||||
subscription: ?Subscription
|
subscription: ?Subscription
|
||||||
|
available*: seq[Availability]
|
||||||
offerExpiryInterval*: UInt256
|
offerExpiryInterval*: UInt256
|
||||||
|
onSale*: OnSale
|
||||||
Availability* = object
|
Availability* = object
|
||||||
id*: array[32, byte]
|
id*: array[32, byte]
|
||||||
size*: uint64
|
size*: uint64
|
||||||
duration*: uint64
|
duration*: uint64
|
||||||
minPrice*: UInt256
|
minPrice*: UInt256
|
||||||
|
OnSale = proc(offer: StorageOffer) {.gcsafe, upraises: [].}
|
||||||
|
|
||||||
func new*(_: type Sales, market: Market): Sales =
|
func new*(_: type Sales, market: Market): Sales =
|
||||||
Sales(market: market, offerExpiryInterval: DefaultOfferExpiryInterval)
|
Sales(market: market, offerExpiryInterval: DefaultOfferExpiryInterval)
|
||||||
|
@ -56,10 +58,20 @@ proc createOffer(sales: Sales,
|
||||||
)
|
)
|
||||||
|
|
||||||
proc handleRequest(sales: Sales, request: StorageRequest) {.async.} =
|
proc handleRequest(sales: Sales, request: StorageRequest) {.async.} =
|
||||||
if availability =? sales.findAvailability(request):
|
without availability =? sales.findAvailability(request):
|
||||||
sales.remove(availability)
|
return
|
||||||
let offer = sales.createOffer(request, availability)
|
|
||||||
await sales.market.offerStorage(offer)
|
sales.remove(availability)
|
||||||
|
|
||||||
|
let offer = sales.createOffer(request, availability)
|
||||||
|
await sales.market.offerStorage(offer)
|
||||||
|
|
||||||
|
var subscription: ?Subscription
|
||||||
|
proc onSelect(offerId: array[32, byte]) {.gcsafe, upraises:[].} =
|
||||||
|
if subscription =? subscription:
|
||||||
|
asyncSpawn subscription.unsubscribe()
|
||||||
|
sales.onSale(offer)
|
||||||
|
subscription = some await sales.market.subscribeSelection(request.id, onSelect)
|
||||||
|
|
||||||
proc start*(sales: Sales) =
|
proc start*(sales: Sales) =
|
||||||
doAssert sales.subscription.isNone, "Sales already started"
|
doAssert sales.subscription.isNone, "Sales already started"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import std/sequtils
|
import std/sequtils
|
||||||
import std/heapqueue
|
import std/heapqueue
|
||||||
|
import pkg/questionable
|
||||||
import pkg/dagger/market
|
import pkg/dagger/market
|
||||||
|
|
||||||
export market
|
export market
|
||||||
|
@ -15,6 +16,7 @@ type
|
||||||
Subscriptions = object
|
Subscriptions = object
|
||||||
onRequest: seq[RequestSubscription]
|
onRequest: seq[RequestSubscription]
|
||||||
onOffer: seq[OfferSubscription]
|
onOffer: seq[OfferSubscription]
|
||||||
|
onSelect: seq[SelectSubscription]
|
||||||
RequestSubscription* = ref object of Subscription
|
RequestSubscription* = ref object of Subscription
|
||||||
market: MockMarket
|
market: MockMarket
|
||||||
callback: OnRequest
|
callback: OnRequest
|
||||||
|
@ -22,23 +24,39 @@ type
|
||||||
market: MockMarket
|
market: MockMarket
|
||||||
requestId: array[32, byte]
|
requestId: array[32, byte]
|
||||||
callback: OnOffer
|
callback: OnOffer
|
||||||
|
SelectSubscription* = ref object of Subscription
|
||||||
|
market: MockMarket
|
||||||
|
requestId: array[32, byte]
|
||||||
|
callback: OnSelect
|
||||||
Expiry = object
|
Expiry = object
|
||||||
future: Future[void]
|
future: Future[void]
|
||||||
expiry: UInt256
|
expiry: UInt256
|
||||||
|
|
||||||
method requestStorage*(market: MockMarket, request: StorageRequest) {.async.} =
|
method requestStorage*(market: MockMarket, request: StorageRequest) {.async.} =
|
||||||
market.requested.add(request)
|
market.requested.add(request)
|
||||||
for subscription in market.subscriptions.onRequest:
|
let subscriptions = market.subscriptions.onRequest
|
||||||
|
for subscription in subscriptions:
|
||||||
subscription.callback(request)
|
subscription.callback(request)
|
||||||
|
|
||||||
method offerStorage*(market: MockMarket, offer: StorageOffer) {.async.} =
|
method offerStorage*(market: MockMarket, offer: StorageOffer) {.async.} =
|
||||||
market.offered.add(offer)
|
market.offered.add(offer)
|
||||||
for subscription in market.subscriptions.onOffer:
|
let subscriptions = market.subscriptions.onOffer
|
||||||
|
for subscription in subscriptions:
|
||||||
if subscription.requestId == offer.requestId:
|
if subscription.requestId == offer.requestId:
|
||||||
subscription.callback(offer)
|
subscription.callback(offer)
|
||||||
|
|
||||||
|
proc findOffer(market: MockMarket, id: array[32, byte]): ?StorageOffer =
|
||||||
|
for offer in market.offered:
|
||||||
|
if offer.id == id:
|
||||||
|
return some offer
|
||||||
|
|
||||||
method selectOffer*(market: MockMarket, id: array[32, byte]) {.async.} =
|
method selectOffer*(market: MockMarket, id: array[32, byte]) {.async.} =
|
||||||
market.selected.add(id)
|
market.selected.add(id)
|
||||||
|
let subscriptions = market.subscriptions.onSelect
|
||||||
|
for subscription in subscriptions:
|
||||||
|
if offer =? market.findOffer(id):
|
||||||
|
if subscription.requestId == offer.requestId:
|
||||||
|
subscription.callback(id)
|
||||||
|
|
||||||
method subscribeRequests*(market: MockMarket,
|
method subscribeRequests*(market: MockMarket,
|
||||||
callback: OnRequest):
|
callback: OnRequest):
|
||||||
|
@ -62,12 +80,27 @@ method subscribeOffers*(market: MockMarket,
|
||||||
market.subscriptions.onOffer.add(subscription)
|
market.subscriptions.onOffer.add(subscription)
|
||||||
return subscription
|
return subscription
|
||||||
|
|
||||||
|
method subscribeSelection*(market: MockMarket,
|
||||||
|
requestId: array[32, byte],
|
||||||
|
callback: OnSelect):
|
||||||
|
Future[Subscription] {.async.} =
|
||||||
|
let subscription = SelectSubscription(
|
||||||
|
market: market,
|
||||||
|
requestId: requestId,
|
||||||
|
callback: callback
|
||||||
|
)
|
||||||
|
market.subscriptions.onSelect.add(subscription)
|
||||||
|
return subscription
|
||||||
|
|
||||||
method unsubscribe*(subscription: RequestSubscription) {.async.} =
|
method unsubscribe*(subscription: RequestSubscription) {.async.} =
|
||||||
subscription.market.subscriptions.onRequest.keepItIf(it != subscription)
|
subscription.market.subscriptions.onRequest.keepItIf(it != subscription)
|
||||||
|
|
||||||
method unsubscribe*(subscription: OfferSubscription) {.async.} =
|
method unsubscribe*(subscription: OfferSubscription) {.async.} =
|
||||||
subscription.market.subscriptions.onOffer.keepItIf(it != subscription)
|
subscription.market.subscriptions.onOffer.keepItIf(it != subscription)
|
||||||
|
|
||||||
|
method unsubscribe*(subscription: SelectSubscription) {.async.} =
|
||||||
|
subscription.market.subscriptions.onSelect.keepItIf(it != subscription)
|
||||||
|
|
||||||
func `<`(a, b: Expiry): bool =
|
func `<`(a, b: Expiry): bool =
|
||||||
a.expiry < b.expiry
|
a.expiry < b.expiry
|
||||||
|
|
||||||
|
|
|
@ -74,3 +74,17 @@ suite "Sales":
|
||||||
await market.requestStorage(request)
|
await market.requestStorage(request)
|
||||||
check market.offered[0].expiry == now + sales.offerExpiryInterval
|
check market.offered[0].expiry == now + sales.offerExpiryInterval
|
||||||
sales.stop()
|
sales.stop()
|
||||||
|
|
||||||
|
test "call onSale when offer is selected":
|
||||||
|
let availability = Availability.init(size=100, duration=60, minPrice=42.u256)
|
||||||
|
sales.add(availability)
|
||||||
|
var selectedOffer: StorageOffer
|
||||||
|
sales.onSale = proc(offer: StorageOffer) =
|
||||||
|
selectedOffer = offer
|
||||||
|
sales.start()
|
||||||
|
let request = StorageRequest(duration:60.u256, size:100.u256, maxPrice:42.u256)
|
||||||
|
await market.requestStorage(request)
|
||||||
|
let offer = market.offered[0]
|
||||||
|
await market.selectOffer(offer.id)
|
||||||
|
check selectedOffer == offer
|
||||||
|
sales.stop()
|
||||||
|
|
Loading…
Reference in New Issue