Weitere ähnliche Inhalte Ähnlich wie Coordinating non blocking io melb-clj (20) Kürzlich hochgeladen (20) Coordinating non blocking io melb-clj3. WHAT IS THE WEB STACK
•
•
•
HttpKit as web server
Compojure for routing
HttpKit for non-blocking http requests
4. REACTIVE APPROACH
PREFERRED
We are not using either Functional Reactive Programming or
Reactive Programming libraries. Eg. Rx.java
• May satisfy other more broad definitions of reactive
• Are making better use of threads than traditional approaches
•
5. Make a payment on a bill
- Not necessarily a full payment
!
POST /bills/:bill-id/payments
Session: user-id
Post Data: amount
!
1. Get credit card token for user
1.1. Send request to payment gateway
2. Find how much was left to be payed
!
If payment is success: render amount remaining on bill
If payment fails: render error
7. SOLUTION 0:
SYNCHRONOUS
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(let
[token
(auth/card-‐token
user-‐id)
details
(bill/details
bill-‐id)
transaction
(payment/bill
bill-‐id
amount
@token)]
(if
(success?
@transaction)
(render-‐remaining-‐response
@details
amount)
error-‐response)))
8. SOLUTION 1:
PROMISE MONAD LET/DO
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(let
[token-‐req
(auth/card-‐token
user-‐id)
details-‐req
(bill/details
bill-‐id)]
(do
[token
token-‐req
transaction
(payment/bill
bill-‐id
amount
token)
details
details-‐req]
(return
(if
(success?
transaction)
(render-‐remaining-‐response
details
amount)
error-‐response)))))
9. SOLUTION 1.1:
PROMISE MONAD LET/DO/DO
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(let
[token-‐req
(auth/card-‐token
user-‐id)
details-‐req
(bill/details
bill-‐id)]
(do
[token
token-‐req
transaction
(payment/bill
bill-‐id
amount
token)]
(if
(success?
transaction)
(do
[details
details-‐req]
(return
(render-‐remaining-‐response
details
amount)))
(return
error-‐response)))))
10. SOLUTION 1.2:
PROMISE MONAD DO
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(do
[token
(auth/card-‐token
user-‐id)
transaction
(payment/bill
bill-‐id
amount
token)
details
(bill/details
bill-‐id)]
(return
(if
(success?
transaction)
(render-‐remaining-‐response
details
amount)
error-‐response))))
11. SOLUTION 1.3:
PROMISE + ERROR MONADS
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(do
[token
(auth/card-‐token
user-‐id)
transaction
(payment/bill
bill-‐id
amount
token)
details
(bill/details
bill-‐id)]
(return
(render-‐remaining-‐response
details
amount))))
12. SOLUTION 2:
PROMISE CHAIN AND LIFT-M-2
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(let
[transaction-‐req
(chain
(promise
user-‐id)
auth/card-‐token
(partial
payment/bill
bill-‐id
amount))
details-‐req
(bill/details
bill-‐id)]
(lift-‐m-‐2
(fn
[transaction
details]
(if
(success?
transaction)
(render-‐remaining-‐response
details
amount)
error-‐response)))
transaction-‐req
details-‐req))
13. SOLUTION 3:
RAW PROMISES
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(let
[transaction-‐req
(-‐>
(auth/card-‐token
user-‐id)
(then
(partial
payment/bill
bill-‐id
amount)))
details-‐req
(bill/details
bill-‐id)]
(when
transaction-‐req
details-‐req
(fn
[transaction
details]
(if
(success?
transaction)
(render-‐remaining-‐response
details
amount)
error-‐response)))))
15. SOLUTION 5:
CORE.ASYNC
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(go
(let
[token
(auth/card-‐token
user-‐id)
details
(bill/details
bill-‐id)
transaction
(payment/bill
bill-‐id
amount
(<!
token))]
(if
(success?
(<!
transaction))
(render-‐remaining-‐response
(<!
details)
amount)
error-‐response))))
16. SOLUTION 6:
LAMINA PIPELINE
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(let
[details-‐req
(bill/details
bill-‐id)]
(pipeline
(auth/card-‐token
user-‐id)
(partial
payment/bill
bill-‐id
amount)
(fn
[transaction]
(if
(success?
transaction)
(on-‐realized
details-‐req
(fn
[details]
(render-‐remaining-‐response
details
amount)))
error-‐response)))))
18. SOLUTION 8:
PULSAR PROMISES
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
#(let
[token
(auth-‐card-‐token
user-‐id)
details
(bill-‐details
bill-‐id)
transaction
(payment-‐bill
bill-‐id
amount
@token)]
(if
(success?
@transaction)
(render-‐remaining-‐response
@details
amount)
error-‐response)))
20. (GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(let
[token
(auth/card-‐token
user-‐id)
details
(bill/details
bill-‐id)
transaction
(payment/bill
bill-‐id
amount
@token)]
(if
(success?
@transaction)
(render-‐remaining-‐response
@details
amount)
error-‐response)))
Synchronous
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
(go
(let
[token
(auth/card-‐token
user-‐id)
details
(bill/details
bill-‐id)
transaction
(payment/bill
bill-‐id
amount
(<!
token))]
(if
(success?
(<!
transaction))
(render-‐remaining-‐response
(<!
details)
amount)
error-‐response))))
core.async
(GET
"/bills/:bill-‐id/payments"
[bill-‐id
user-‐id
amount]
#(let
[token
(auth-‐card-‐token
user-‐id)
details
(bill-‐details
bill-‐id)
transaction
(payment-‐bill
bill-‐id
amount
@token)]
(if
(success?
@transaction)
(render-‐remaining-‐response
@details
amount)
(error-‐response))))
Pulsar
21. SCALA
def
payBill(billId:
Integer,
userId:
Integer,
amount:
Integer):Future[Option[Json]]
=
{
val
seq
=
for
{
token
<-‐
Auth.cardToken(userId)
tr
<-‐
Payment.bill(token)
}
yield
tr
async
{
val
transactionProcess
=
await(seq.run)
val
detailProcess
=
await(BillOps.details(billId))
for
{
transaction
<-‐
transactionProcess
detail
<-‐
detailProcess
}
yield
renderRemainingResponse(amount,
detail)
}
}
23. HELLO WORLD
• Single
C1-Medium
• 7GB
•8
Ram
Cores
• 313,852
Concurrent Users
• 4756.79
Requests Per
Second
• More
meaningful results
once in SVT with full
implementation
24. ALL DONE AT
AUSTRALIA POST
DIGITAL MAILBOX
They're hiring.
Send your CV to
APDMRecruitment@auspost.com.au