1

This is a follow-up to a question from How to iterate over values upon validation

In my bid service I'd like to make sure that each submitted bid has a price higher than the one before. However, several bids may be submitted by different users at at the same time. This means:

  1. I'd like to "lock" each submitted bid, validate it against that previous ones, save if it's valid or reject if not, and then break that lock. That is, each bid should be processed one at a time, and not in parallel.
  2. Next, Move on to the next bid. Validate it as-well, making sure the previous one's price is taken into account.

How would I approach this? I assume STM needs to come into play here, but I haven't seen such an example on IHP yet.

amitaibu
  • 1,026
  • 1
  • 7
  • 23

1 Answers1

0

Assuming you have some validation function with a type like

validate :: Bid -> Bid -> Bool

you could simple use an MVar to store your Bid. Like this:

receiveBid :: MVar Bid -> Bid -> IO Bool
receiveBid m b = do
    b' <- takeMVar m
    let valid = validate b b'
    putMVar valid
    pure valid

Of course, you're probably going to want to store bids for multiple items, but normal data structures can get you where you need to go there.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • Thanks. I think I understand the `MVar` part, which will make sure only one bid is processed at a time. I'm not sure however how to wire it into the IHP Controller. Where would be `MVar Bid` be held? – amitaibu Sep 26 '21 at 07:33
  • Actually, I'm not sure MVar would work here. My idea is that a Bid would be saved to the DB if it's valid. So I wouldn't need to hold another MVar with the latest Bid (also due to the reason that I'd like to have other validations on other Bids of that Item). So I think what I need is to make `action CreateBidAction = do` somehow sequential – amitaibu Sep 26 '21 at 12:02
  • @amitaibu If you're using a database, then probably the correct thing is to write a query that does the validation and update all in one transaction. – Daniel Wagner Sep 26 '21 at 16:18