mirror of
https://github.com/codex-storage/nim-codex.git
synced 2025-02-21 17:18:22 +00:00
86 lines
2.3 KiB
Nim
86 lines
2.3 KiB
Nim
|
import pkg/chronos
|
||
|
import pkg/upraises
|
||
|
import pkg/stint
|
||
|
import ./statemachine
|
||
|
import ./states/[downloading, unknown]
|
||
|
import ../contracts/requests
|
||
|
import ../rng
|
||
|
|
||
|
proc newSalesAgent*(sales: Sales,
|
||
|
requestId: RequestId,
|
||
|
availability: ?Availability,
|
||
|
request: ?StorageRequest): SalesAgent =
|
||
|
SalesAgent(
|
||
|
sales: sales,
|
||
|
requestId: requestId,
|
||
|
availability: availability,
|
||
|
request: request)
|
||
|
|
||
|
# fwd declarations
|
||
|
proc subscribeCancellation*(agent: SalesAgent): Future[void] {.gcsafe.}
|
||
|
proc subscribeFailure*(agent: SalesAgent): Future[void] {.gcsafe.}
|
||
|
|
||
|
proc populateRequest(agent: SalesAgent) {.async.} =
|
||
|
if agent.request.isNone:
|
||
|
agent.request = await agent.sales.market.getRequest(agent.requestId)
|
||
|
|
||
|
proc init*(agent: SalesAgent, numSlots: uint64) {.async.} =
|
||
|
let rng = Rng.instance
|
||
|
let slotIndex = rng.rand(numSlots - 1)
|
||
|
agent.slotIndex = some slotIndex.u256
|
||
|
|
||
|
# TODO: try not to block the thread waiting for the network
|
||
|
await agent.populateRequest()
|
||
|
await agent.subscribeCancellation()
|
||
|
await agent.subscribeFailure()
|
||
|
|
||
|
proc deinit*(agent: SalesAgent) {.async.} =
|
||
|
try:
|
||
|
await agent.fulfilled.unsubscribe()
|
||
|
except CatchableError:
|
||
|
discard
|
||
|
try:
|
||
|
await agent.failed.unsubscribe()
|
||
|
except CatchableError:
|
||
|
discard
|
||
|
if not agent.cancelled.completed:
|
||
|
await agent.cancelled.cancelAndWait()
|
||
|
|
||
|
proc subscribeCancellation*(agent: SalesAgent) {.async.} =
|
||
|
let market = agent.sales.market
|
||
|
|
||
|
proc onCancelled() {.async.} =
|
||
|
let clock = agent.sales.clock
|
||
|
|
||
|
without request =? agent.request:
|
||
|
return
|
||
|
|
||
|
await clock.waitUntil(request.expiry.truncate(int64))
|
||
|
await agent.fulfilled.unsubscribe()
|
||
|
without state =? (agent.state as SaleState):
|
||
|
return
|
||
|
await state.onCancelled(request)
|
||
|
|
||
|
agent.cancelled = onCancelled()
|
||
|
|
||
|
proc onFulfilled(_: RequestId) {.async.} =
|
||
|
agent.cancelled.cancel()
|
||
|
|
||
|
agent.fulfilled =
|
||
|
await market.subscribeFulfillment(agent.requestId, onFulfilled)
|
||
|
|
||
|
proc subscribeFailure*(agent: SalesAgent) {.async.} =
|
||
|
let market = agent.sales.market
|
||
|
|
||
|
proc onFailed(_: RequestId) {.async.} =
|
||
|
without request =? agent.request:
|
||
|
return
|
||
|
|
||
|
without state =? (agent.state as SaleState):
|
||
|
return
|
||
|
|
||
|
await state.onFailed(request)
|
||
|
|
||
|
agent.failed =
|
||
|
await market.subscribeRequestFailed(agent.requestId, onFailed)
|